psi*_*lia 2 c c++ algorithm performance bit-manipulation
我编写了一个函数,它读取字节的输入缓冲区并产生一个字输出缓冲区,其中每个字对于输入缓冲区的每个ON位可以是0x0081,对于每个OFF位都可以是0x007F.给出输入缓冲区的长度.两个阵列都有足够的物理位置.我也有大约2Kbyte的空闲RAM,我可以用于查找表等.
现在,我发现这个功能是我在实时应用程序中的瓶颈.它将被频繁调用.您能否提出一种如何优化此功能的方法?我看到一种可能性是只使用一个缓冲区并进行就地替换.
void inline BitsToWords(int8 *pc_BufIn,
int16 *pw_BufOut,
int32 BufInLen)
{
int32 i,j,z=0;
for(i=0; i<BufInLen; i++)
{
for(j=0; j<8; j++, z++)
{
pw_BufOut[z] =
( ((pc_BufIn[i] >> (7-j))&0x01) == 1?
0x0081: 0x007f );
}
}
}
Run Code Online (Sandbox Code Playgroud)
请不要提供任何库,编译器特定或CPU /硬件特定的优化,因为它是一个多平台项目.
我还有大约2Kbyte空闲RAM,我可以用于查找表
您的查找表可以const在编译时放在一个数组中,因此它可以在ROM中 - 这是否为您提供了直接4KB表的空间?
如果你可以负担4KB的ROM空间,唯一的问题是将表构建为.c文件中的初始化数组- 但只需要执行一次,你可以编写一个脚本来执行它(这可能有助于确保它是正确的,如果您决定表格将来因某种原因需要更改,也可能会有帮助.
您必须进行配置以确保从ROM到目标阵列的副本实际上比计算需要进入目标的速度更快 - 如果有以下内容,我不会感到惊讶:
/* untested code - please forgive any bonehead errors */
void inline BitsToWords(int8 *pc_BufIn,
int16 *pw_BufOut,
int32 BufInLen)
{
while (BufInLen--) {
unsigned int tmp = *pc_BufIn++;
*pw_BufOut++ = (tmp & 0x80) ? 0x0081 : 0x007f;
*pw_BufOut++ = (tmp & 0x40) ? 0x0081 : 0x007f;
*pw_BufOut++ = (tmp & 0x20) ? 0x0081 : 0x007f;
*pw_BufOut++ = (tmp & 0x10) ? 0x0081 : 0x007f;
*pw_BufOut++ = (tmp & 0x08) ? 0x0081 : 0x007f;
*pw_BufOut++ = (tmp & 0x04) ? 0x0081 : 0x007f;
*pw_BufOut++ = (tmp & 0x02) ? 0x0081 : 0x007f;
*pw_BufOut++ = (tmp & 0x01) ? 0x0081 : 0x007f;
}
}
Run Code Online (Sandbox Code Playgroud)
最终变得更快.我期望该函数的优化构建将把所有内容都放在寄存器中或编码到指令中,除了每个输入字节的单个读取和每个输出字的单个写入.或者非常接近.
您可以通过一次处理多个输入字节来进一步优化,但是您必须处理对齐问题以及如何处理不是您正在处理的块大小的倍数的输入缓冲区.这些问题不是难以处理的问题,但它们确实使问题复杂化,并且不清楚您可能期望获得哪种改进.