我有一个函数,它接受通过DMA通过SPI接收的一些数据。为了提高通过SPI传输的速度,三个10位数据段被打包成一个32位字(带有两个填充位)。收到后,我需要将其解压缩成三个16位字(10个实际数据位和6个填充位)。
这个函数经常被调用,所以任何速度优化都会大大改善整体执行时间。它运行在STMicro Cortex M3上,使用IAR EWARM7.10作为编译器,优化设置为高,针对速度进行了优化。
/*******************************************************************************
* Function Name : Unpack
* Description : the previous adc sample has been
DMA'd into an array
unpack each 32 bit transfer into 3, 10bit samples
( low 16 spi word ) ( high 16 spi word )
{ p15 p14 ch1_9:0 ch2_9:0 ch3_9:0 } 32 bit packing
* Input : output buf 16 bit word (10 bit adc, right justified)
input buf 32 bit data
count in 32 bit input words
* Output : None.
* Return : None.
*******************************************************************************/
void Unpack( u16* pDest, u16* pSrc, u16 packed32_count)
{
u16 i;
u32 n;
u16 dest_index = 0;
u16 src_index = 0;
for ( i = 0; i < packed32_count ; i++ )
{
n = pSrc[src_index]; //get high 16
n <<= 16;
n |= pSrc[src_index+1]; //get low 16
src_index+=2;
pDest[dest_index+2] = n & 0x3ff;
n >>= 10;
pDest[dest_index+1] = n & 0x3ff;
n >>= 10;
pDest[dest_index] = n & 0x3ff;
dest_index+=3;
}
} 发布于 2014-07-23 20:33:41
下面的代码不是很多,但可能比上面的代码更快。此外,您还可以尝试使用影响速度的优化进行编译。
void Unpack( u16* pDest, u32* pSrc, u16 packed32_count)
{
int i;
u32 val;
for(i = 0; i < packed32_count; i++)
{
val = pSrc[i];
pDest[2] = val & 0x3ff;
pDest[1] = (val >> 10) & 0x3ff;
pDest[0] = val >> 20;
pDest += 3;
}
}发布于 2014-07-23 20:34:17
这可能会更快一点
void Unpack( u16* pDest, u16* pSrc, u16 packed32_count)
{
u32 n;
u16* pSrcEnd = pSrc + 2 * packed32_count;
while (pSrc < pSrcEnd)
{
n = *pSrc++; //get high 16
n <<= 16;
n |= *pSrc++; //get low 16
*pDest++ = (n>>20) & 0x3ff;
*pDest++ = (n>>10) & 0x3ff;
*pDest++ = n & 0x3ff;
}
}发布于 2014-07-23 20:27:13
假设您的处理器是高字节顺序的(如果不是,您可以在打包中对此进行排序,使打包/解包对称),您可以使用以下内容加载数据:
n = ((u32*)pSrc)[src_index++];而且,使用u32索引可能比使用u16更快。如果您有32位寄存器,则使用16位寄存器效率不高。
您可以使用register,但我怀疑优化器已经这样做了:
register u32 src_index; 但是如果这是经常使用的,你真的应该看看生成的汇编代码(例如,当使用16位变量时,检查是否存在低效)。
https://stackoverflow.com/questions/24910227
复制相似问题