从两个128位块中收集四个32位字

时间:2017-12-03 10:07:57

标签: c arm intrinsics neon

我正在使用C intrinsics从SSE到NEON的端口。我有两个由32位字组成的128位块:

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

我需要将它们收集到两个uint32x4_t中,如下所示:

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

128位的块及其相关的步幅给我带来了麻烦。我已经回顾了ARM的NEON Part 1: Load and Stores,但是我看不到两个16字节块的内容。

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

1 个答案:

答案 0 :(得分:3)

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矩阵乘法(浮点数,复数)的运行速度几乎是我的"勺子喂养"内部版本,由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指令。