将32位数组复制到16位数组的最快方法是什么?

时间:2013-07-22 14:41:02

标签: c memcpy

将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];

4 个答案:

答案 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数组进行类型转换,以便在一个插槽中存储两个值。

除非您的所有算法(您将在阵列上应用)与此元素布局无缝地工作,否则最后一种方法无法保证为您提供更好的性能。也许您必须稍微修改算法才能使用此数据结构。对于例如一些位操作算法(和/或等)可以应用于这种数据结构,而无需太多工作。