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. mapbox展示动态图标

    mapbox-gl通过为marker设置css动画,实现动态闪烁效果,先放个效果图 . 1.主要就是为元素设置一个动画, myfirst动画让元素随时间放大 .marker { /* backgrou ...

  2. 【leetcode】1240. Tiling a Rectangle with the Fewest Squares

    题目如下: Given a rectangle of size n x m, find the minimum number of integer-sided squares that tile th ...

  3. IDEA创建类似于Eclipse的source folder

    1.新建普通文件夹目录directory 2.当前Module右键Open Mudule Settings(F12) 3.选中新建的文件夹并单击上面的Sources,看到文件夹颜色变化即成功.

  4. 001_ARM学习_六大类指令集---LDR、LDRB、LDRH、LDM、STR、STRB、STRH、STM

    以下内容为转载: 注:非常感谢博主“希望之光”,文章转自他的博客:http://blog.chinaunix.net/uid-20379123-id-1956584.html   ARM的六大类指令集 ...

  5. ueditor+word图片上传

    最近公司做项目需要实现一个功能,在网页富文本编辑器中实现粘贴Word图文的功能. 我们在网站中使用的Web编辑器比较多,都是根据用户需求来选择的.目前还没有固定哪一个编辑器 有时候用的是UEditor ...

  6. 路由器配置——DHCP+DHCP中继服务配置

    一.实验目的:掌握DHCP服务基本配置及DHCP中继服务配置,实现全网互通 二.拓扑图: 三.具体步骤配置: (1)R1路由器配置: Router>enable  --进入特权模式 Router ...

  7. Vs中包含目录、库目录、附加包含目录、附加库目录、附加依赖项之详解

    VS项目中的包含目录.库目录.附加包含目录.附加库目录.附加依赖项均在"项目->属性->配置属性"下进行配置,具体说明如下: VC++目录: 包含目录:寻找#inclu ...

  8. 十一、FHS基础原理

      文件系统: http://note.youdao.com/noteshare?id=298f02714da5b9483429a40dda667f35&sub=6120396419BA477 ...

  9. mybatis中foreach参数过多效率很慢的优化

    foreach 后面in 传入的参数有1万条,#和$是有效率区别的,$的效率远高于#,上篇文章做了比较. 但没达到我的理想结果. 1. 更改方式,把foreach 去掉,改成拼装方式, 参数直接拼装成 ...

  10. 第11组 Beta冲刺(3/5)

    第11组 Beta冲刺(3/5)   队名 不知道叫什么团队 组长博客 https://www.cnblogs.com/xxylac/p/12006665.html 作业博客 https://edu. ...