将 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];
在带有 Neon 指令集的 ARM cortex A8 上,最快的方法使用交错的读/写指令:
vld2.16 {d0,d1}, [r0]!
vst1.16 {d0}, [r1]!
或饱和指令将 32 位整数向量转换为 16 位整数向量。
这两种方法都可以在 c 中使用 gcc 内在函数。gcc 也有可能自动矢量化精心编写的 c 代码,只使用这些特定指令。这基本上需要与这些指令的所有副作用和 c 代码一一对应。
没有执行此操作的标准函数,主要是因为它非常特定于您的应用程序。
如果您知道 in 中的整数tab32
将足够小以适合 uint16_t,那么您问题中的代码可能是您可以获得的最好的代码(如果编译器可以优化某些东西,它将完成其余的工作)。
在我看来,使用 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(bytes),然后在 int-array 上进行 (char*) 类型转换以将两个值存储在一个插槽中。
最后一种方法不能保证给您更好的性能,除非您的所有算法(您将在数组上应用)与这种元素布局无缝协作。也许您必须稍微修改算法才能使用此数据结构。例如,一些位操作算法(和,或等)可以应用到这个数据结构上,而无需做太多工作。
好吧,如果您不需要修改数据,则可以在 32 位数组上使用指向 uint16_t 的指针。它假设裸内存作为 16 位无符号整数数组是有意义的。
编辑:搁置,问题中有些不清楚