将32位阵列复制到16位阵列的最佳方法是什么?
我知道“memcpy”使用硬件指令。但是有没有标准函数来复制每个元素中“更改大小”的数组?
我使用gcc作为armv7(皮质A8)。
uint32_t tab32[500];
uint16_t tab16[500];
for(int i=0;i<500;i++)
tab16[i]=tab32[i];
答案 0 :(得分:4)
在带有Neon指令集的ARM cortex A8上,最快的方法使用交错读/写指令:
vld2.16 {d0,d1}, [r0]!
vst1.16 {d0}, [r1]!
或用于将32位整数的向量转换为16位整数向量的饱和指令。
这两种方法都可以在c中使用gcc intrinsic。 gcc也可以自动向量化一个精心编写的c代码,只使用这些特定的指令。这基本上要求与这些指令和c代码的所有副作用一一对应。
答案 1 :(得分:3)
没有标准功能可以做到这一点,主要是因为它对您的应用程序非常具体。
如果您知道tab32
中的整数足够小以适合uint16_t,那么您的问题中的代码可能是您可以获得的最佳代码(如果可以优化某些内容,编译器将完成其余的工作)
答案 2 :(得分:0)
如果您不需要修改数据,可以在32位数组上使用指向uint16_t的指针。它假设裸存储器是一个16位无符号整数数组。
编辑:暂停,问题中的内容不明确
答案 3 :(得分:0)
在我看来,使用memcpy将是最快的方法。 memcpy是针对每个架构单独优化的,所以你应该做得很好。
另一方面,由于ARM中的寄存器为32位,因此后端的16位值为零/符号扩展为32位。因此,我认为,将它们保留为32位阵列而不是将数据复制到16位阵列会更有效(实际上应该测量以做出正确的决定)。
有一种方法可以节省大小并提高性能(希望如果)如果将传入值存储在一个int数组中,但每个int将有两个16位值。
For example: int[4] would look like this:
----------------------------------------------------------------
| 32bit || 32bit || 32bit || 32bit |
----------------------------------------------------------------
| 16bit | 16bit|| 16bit | 16bit|| 16bit | 16bit|| 16bit | 16bit|
----------------------------------------------------------------
需要进行一些预处理(比如将值读取为char(字节),然后,(char *)对int数组进行类型转换,以便在一个插槽中存储两个值。
除非您的所有算法(您将在阵列上应用)与此元素布局无缝地工作,否则最后一种方法无法保证为您提供更好的性能。也许您必须稍微修改算法才能使用此数据结构。对于例如一些位操作算法(和/或等)可以应用于这种数据结构,而无需太多工作。