C-从两个128位块中收集四个32位单词



我正在使用c Intrinsics在从SSE到霓虹灯的端口上工作。我有两个由32位单词制成的128位块:

[A1  A2  A3  A4] [B1  B2  B3  B4]

,我需要将它们聚集到两个uint32x4_t中:

[A1  B1  A2  B2] [A3  B3  A4  B4]

128位街区及其相关的大步使我感到麻烦。我已经回顾了ARM的霓虹灯第1部分:负载和存储,但我看不到两个16字节块的东西。

如何从两个128位块中收集数据?

VZIP.32正是您要寻找的

from MSB to LSB:
q0: A4 | A3 | A2 | A1
q1: B4 | B3 | B2 | B1
vzip.32 q0, q1
q0: B2 | A2 | B1 | A1
q1: B4 | A4 | B3 | A3

aarch64上,这完全不同。

from MSB to LSB:
v0: A4 | A3 | A2 | A1
v1: B4 | B3 | B2 | B1
zip2 v2.4s, v0.4s, v1.4s
zip1 v3.4s, v0.4s, v1.4s
v2: B2 | A2 | B1 | A1
v3: B4 | A4 | B3 | A3

,您不应该浪费时间在内在。

我的汇编版本4x4矩阵乘法(float,copplect)的运行速度几乎是我的"汤匙喂养"内在版本的三倍,该版本由Clang编辑。

*gcc(7.1.1)编译的版本略高于clang的速度,但效果不多。


以下是使用32位整数作为示例的内在版本。它在A-32 NEON,AARCH32和AARCH64。

上工作。
uint32x4_t vecA, vecB;
...
uint32x4x2_t vecR = vzipq_u32(vecA, vecB);
uint32x4_t vecX = vecR.val[0];
uint32x4_t vecY = vecR.val[1];

请注意,vzip2结合了第一个(下半部),而vzip1进行第二(上)。uint32x4x2_tval[0]val[1]访问它们。一旦访问val[],编译器就可以选择zip1zip2指令。

最新更新