1、背景

STM32 MCU对25.6Kb数据进行压缩,丢掉每个数据的低4位然后2个字节拼接为1个字节。发现处理耗时竞达1ms以上,于是开始进行优化,最后达到200us的效果,提速5倍以上。

2、优化

2.1优化前

  HAL_GPIO_WritePin(TestPB12_GPIO_Port, TestPB12_Pin, );
#if (USE_BINNING)
ImgCompressTo4Bit(img_ptr + PACKAGE_HEADER_SIZE, ImgSampBuf, IMG_SIZE);
#else
memcpy(img_ptr + PACKAGE_HEADER_SIZE, ImgSampBuf, IMG_SIZE);
#endif
HAL_GPIO_WritePin(TestPB12_GPIO_Port, TestPB12_Pin, );

该处理过程耗时1ms60us。

2.2 第一次优化

考虑到过多的for循环,会导致效率变低,于是一次处理4个字节。

/**
* @brief compress a arrary with high 4bit and low 4bit.
* @param[out] *pDst arrary to be filled
* @param[in] *pSrc input arrary
* @param[in] len src length
* @return dst length.
*
*/
int ImgCompressTo4Bit(uint8_t *pDst, uint8_t *pSrc, int srcLen)
{
/*loop Unrolling */
uint32_t dstLen = srcLen >> ;
uint32_t blkCnt = dstLen >> 2u; uint32_t halfOffset = dstLen;
uint8_t * ptrHigh = pSrc; // high 4 bit
uint8_t * ptrLow = pSrc + halfOffset; // low 4 bit while(blkCnt > 0u)
{
*pDst++ = ((*ptrHigh++) & 0xF0) | (((*ptrLow++) & 0xF0)>>);
*pDst++ = ((*ptrHigh++) & 0xF0) | (((*ptrLow++) & 0xF0)>>);
*pDst++ = ((*ptrHigh++) & 0xF0) | (((*ptrLow++) & 0xF0)>>);
*pDst++ = ((*ptrHigh++) & 0xF0) | (((*ptrLow++) & 0xF0)>>);
blkCnt--;
} blkCnt = dstLen % 0x4u; while(blkCnt > 0u)
{
*pDst++ = ((*ptrHigh++) & 0xF0) | (((*ptrLow++) & 0xF0)>>);
blkCnt--;
} return dstLen;
}

优化后:一次处理4个数据时间为640us。如果进一步 一次处理8个数据,时间为600us。

2.3 第二次优化

考虑到MCU是32位机器,那么使用u32类型数据进行处理,可以提高效率。

int ImgCompressTo4Bit(uint8_t *pDst, uint8_t *pSrc, int srcLen)
{
/*loop Unrolling */
uint32_t dstLen = srcLen >> ;
uint32_t blkCnt = dstLen >> 2u; uint32_t halfOffset = dstLen;
uint32_t * ptrHigh = (uint32_t*)pSrc; // high 4 bit
uint32_t * ptrLow = (uint32_t*)(pSrc + halfOffset); // low 4 bit
uint32_t * dst = (uint32_t*)pDst; while(blkCnt > 0u)
{
*dst++ = ((*ptrHigh++) & 0xF0F0F0F0) | (((*ptrLow++) & 0xF0F0F0F0)>>);
blkCnt--;
} blkCnt = dstLen % (0x4u); while(blkCnt > 0u)
{
*dst++ = ((*ptrHigh++) & 0xF0F0F0F0) | (((*ptrLow++) & 0xF0F0F0F0)>>);
blkCnt--;
} return dstLen;
}

优化后速度达到240us。

2.4 第三次优化

同样考虑降低for循环的次数,一次处理4个u32,实际上是16个字节的数据。

int ImgCompressTo4Bit(uint8_t *pDst, uint8_t *pSrc, int srcLen)
{
/*loop Unrolling */
uint32_t dstLen = srcLen >> ;
uint32_t blkCnt = dstLen >> 2u >> 2u; uint32_t halfOffset = dstLen;
uint32_t * ptrHigh = (uint32_t*)pSrc; // high 4 bit
uint32_t * ptrLow = (uint32_t*)(pSrc + halfOffset); // low 4 bit
uint32_t * dst = (uint32_t*)pDst; while(blkCnt > 0u)
{
*dst++ = ((*ptrHigh++) & 0xF0F0F0F0) | (((*ptrLow++) & 0xF0F0F0F0)>>);
*dst++ = ((*ptrHigh++) & 0xF0F0F0F0) | (((*ptrLow++) & 0xF0F0F0F0)>>);
*dst++ = ((*ptrHigh++) & 0xF0F0F0F0) | (((*ptrLow++) & 0xF0F0F0F0)>>);
*dst++ = ((*ptrHigh++) & 0xF0F0F0F0) | (((*ptrLow++) & 0xF0F0F0F0)>>);
blkCnt--;
} blkCnt = dstLen % (0x4u*0x4u); while(blkCnt > 0u)
{
*dst++ = ((*ptrHigh++) & 0xF0F0F0F0) | (((*ptrLow++) & 0xF0F0F0F0)>>);
blkCnt--;
} return dstLen;
}

优化后速度达到180--200us左右。

3、总结

基于c语法的优化:减少循环处理的次数。

基于芯片特性的优化:使用u32数据,提高处理效率。

经过3次简单的优化,1ms60us的处理降低到200us实现原有的操作。

STM32 MCU一次计算优化和提速的更多相关文章

  1. 如何获取STM32 MCU的唯一ID

    前段时间由于应用需要对产品授权进行限制,所以研究了一下有关STM32 MCU的唯一ID的资料,并最终利用它实现了我们的目标. 1.基本描述 在STM32的全系列MCU中均有一个96位的唯一设备标识符. ...

  2. 基于STM32的uCGUI移植和优化

    基于STM32的uCGUI移植和优化 首先在开始这个说明之前,要简要说明下具体的环境: 编译工具:MDK4.20 开发板:安富莱v2版开发板 调试器:JLink  v8盗版 移植篇 相信大家有移植经验 ...

  3. STM32 程序所占用空间计算 && FLASH存储的起始地址计算

    程序编译完成,会乘车program size .. 对STM32容量选型或者 计算FLASH 充当EEPROM起始地址时会用到此参数. 按照下面截图  程序空间 = (16700+732+4580)/ ...

  4. appium-基础搭建,适配,问题,优化,提速

    搭建开发环境,导入testng/log4j/maven 1.配置jdk环境 2.安装appium,下载eclipse-adt,配置appium环境 github.com/getlantern/foru ...

  5. 如何获取STM32 MCU的唯一ID及应用(转)

    源: 如何获取STM32 MCU的唯一ID

  6. MyEclipse6.5的速度性能优化大提速(转)

    MyEclipse是Eclipse的插件,也是一款功能强大的J2EE集成开发环境,支持代码编写.配置.测试以及除错.现在看一下MyEclipse6.5版本的速度性能优化大提速.优化MyEclipse6 ...

  7. 2019牛客多校第二场F Partition problem 暴力+复杂度计算+优化

    Partition problem 暴力+复杂度计算+优化 题意 2n个人分成两组.给出一个矩阵,如果ab两个在同一个阵营,那么就可以得到值\(v_{ab}\)求如何分可以取得最大值 (n<14 ...

  8. 递归、尾递归和使用Stream延迟计算优化尾递归

    我们在学数据结构的时候必然会接触栈(Stack),而栈有一个重要的应用是在程序设计语言中实现递归.递归用途十分广泛,比如我们常见的阶乘,如下代码: 1234 public static int (in ...

  9. 谈反应式编程在服务端中的应用,数据库操作优化,提速 Upsert

    反应式编程在客户端编程当中的应用相当广泛,而当前在服务端中的应用相对被提及较少.本篇将介绍如何在服务端编程中应用响应时编程来改进数据库操作的性能. 开篇就是结论 接续上一篇<谈反应式编程在服务端 ...

随机推荐

  1. fadeTo([[speed],opacity,[easing],[fn]])

    fadeTo([[speed],opacity,[easing],[fn]]) 概述 把所有匹配元素的不透明度以渐进方式调整到指定的不透明度,并在动画完成后可选地触发一个回调函数.大理石机械构件维修 ...

  2. sql server 复习笔记2

    主键约束 可以通过定义primary key 约束来定义主键, 用于强制表的实体化完整性,一个表只能有一个主键约束, 并且primary key 约束中的列不能为空值,由于primary key 约束 ...

  3. robocopy复制大文件

    需要把win7某个盘的资料复制到移动硬盘保存,用xcopy 结果出现内存不足的错误 我的资料约50G  一查才发现要用RoboCopy.在cmd中试了一下,发现真是白用了这么多年win7,都马上要淘汰 ...

  4. LOJ #121. 「离线可过」动态图连通性 LCT维护最大生成树

    这个还是比较好理解的. 你考虑如果所有边构成一棵树的话直接用 LCT 模拟一波操作就行. 但是可能会出现环,于是我们就将插入/删除操作按照时间排序,然后依次进行. 那么,我们就要对我们维护的生成树改变 ...

  5. C语言学习笔记2-程序基础和变量

    本系列文章由jadeshu编写,转载请注明出处.http://blog.csdn.net/jadeshu/article/details/50751977 作者:jadeshu   邮箱: jades ...

  6. 三十、CentOS 7之systemd

    一.系统启动流程 POST --> bootloader  --> MBR工作 --> kernel(initramfs/initrd) --> ro rootfs --> ...

  7. CF1217B

    CF1217B 题意: 有一个有 $ x $ 个头的龙,你有 $ n $ 种方案,每种方案中包含你可以砍掉的头 $ d_i $ 和龙会生长的头 $ h_i $ 找到一种方案,使得操作数最少. 解法: ...

  8. ROS Topic 常用指令

    rostopic list rosnode list一樣,就是列出目前運行中的topic有哪些. rostopic echo <topic_name> 接下來這個指令比較重要啦,就是去監聽 ...

  9. jmeter连接oracle数据库

    == 下载及添加这个文件到 这个路径下 连接设置: 测试连接 链接: https://pan.baidu.com/s/1W0YcVf4VLdsjnxv5umKngQ 提取码: np7j

  10. 《你不知道的JavaScript(上)》笔记——作用域闭包

    当函数可以记住并访问所在的词法作用域时, 就产生了闭包, 即使函数是在当前词法作用域之外执行. function wait(message) { setTimeout( function timer( ...