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. animation-timing-function

    animation-timing-function 语法: animation-timing-function:<single-animation-timing-function>[,&l ...

  2. npm源管理

    1. 安装淘宝镜像 为了提高npm的安装速度,可以使用淘宝镜像. 使用淘宝镜像的方法有两种: 1. npm install -g cnpm --registry=https://registry.np ...

  3. Dynamic Data linq to SQL Web Application

    微软提供了一个数据驱动网站模板,可以自动生成CRUD页面,使用过程中碰到些问题 1.首先是如何应用,只需要创建个context并且在Global.asax里面加入下面这一句就可以了 DefaultMo ...

  4. 【线性代数】6-5:正定矩阵(Positive Definite Matrices)

    title: [线性代数]6-5:正定矩阵(Positive Definite Matrices) categories: Mathematic Linear Algebra keywords: Po ...

  5. NVMe - NB的特性

    翻译一下,纯粹是为了记住这些特性: NVMe provides the following benefits: ● Ultra-low latency 非常低的延迟 ● Very high throu ...

  6. mac 安装oh-my-zsh的问题

    安装完,如果想切换回mac原来的bash终端,可以: chsh -s /bin/bash 反之,切换回zsh: chsh -s /bin/zsh

  7. JAVA RPC 生产级高可用RPC框架使用分享

    先放出链接,喜欢的给个star:https://gitee.com/a1234567891/koalas-rpc 一:项目介绍 koalas-RPC 个人作品,提供大家交流学习,有意见请私信,欢迎拍砖 ...

  8. Notepad++编辑.sh文件

    使用记事本创建创建test.txt文件,修改后缀名为sh后,再文件里写以下内容: #!/bin/bash echo "hello world" 这样的文件再linux里是无法执行的 ...

  9. fatal: unable to access 'https://github.com/Homebrew/brew/'

    最近安装 Homebrew 遇到的坑,总结一下. 我的 Mac 版本是 10.13.6. 首先安装 Homebrew /usr/bin/ruby -e "$(curl -fsSL https ...

  10. arcpy workspace already in transaction mode

    arcpy workspace already in transaction mode RuntimeError: workspace already in transaction mode 同一个工 ...