如何有效地转置表示为四个int32x4t值的矩阵?我不能使用ld4q_s32和st4q_s32。
int32x4t
ld4q_s32
st4q_s32
o3imoua41#
转置通常以递归形式实现:
[A B]' == [A' C'] [C D] [B' D']
其中每个A,B,C,D可以被认为是一个方阵(并且对于1x 1矩阵,A’== A)。不幸的是,使用转置只能在需要并行转置最低2x2矩阵的级别上帮助您-ARM 64指令集缺少转置最高级别的指令,即一次64位,在arm-v7上作为swp d2, d0完成。反正转置还有另一个迭代公式:它会反复地解压或压缩输入。在 *octave/matlab语言 * 中,我们将zip运算符定义为1,它取数组a的前N/2个元素,并将它们与数组的最后N/2个元素交织。
A,B,C,D
swp d2, d0
a
zip = @(a) [a(1:end/2);a(end/2+1:end)](:)'; zip(0:15) %--> 0 8 1 9 2 10 3 11 4 12 5 13 6 14 7 15 zip(ans) %--> 0 4 8 12 1 5 9 13 2 6 10 14 3 7 11 15
因此,使用intrinsic的完整代码可能如下所示:
inline int32x4x4_t zip(int32x4x4_t a) { return { vzip1q_s32(a.val[0], a.val[2]), vzip2q_s32(a.val[0], a.val[2]), vzip1q_s32(a.val[1], a.val[3]), vzip2q_s32(a.val[1], a.val[3]) }; } int32x4x4_t transpose(int32x4x4_t a) { return zip(zip(a)); }
在某些架构中,如果有8个额外的寄存器备用(4个用于索引,4个用于输出),也可以使用vtbl
vtbl
uint8x16x4_t transpose_vtbl(uint8x16x4_t a) { return { vqtbl4q_u8(a, idx0), vqtbl4q_u8(a, idx1), vqtbl4q_u8(a, idx2), vqtbl4q_u8(a, idx3)}; }
在这里,int32x4x4_t input需要与vreinterpretq_u8_s32(input.val[i])进行元素转换,然后返回,idx0的值为0 1 2 3 16 17 18 19 32 33 34 35 48 49 50 51、idx1 == idx0 + 4等。在M1或M2上,VTBL似乎是指令级并行化,与例如相反。中度最近的皮层A75(v8.2),其中vtbl花费3 N +1个时钟周期,没有双发出能力。
int32x4x4_t input
vreinterpretq_u8_s32(input.val[i])
idx0
0 1 2 3 16 17 18 19 32 33 34 35 48 49 50 51
idx1 == idx0 + 4
1条答案
按热度按时间o3imoua41#
转置通常以递归形式实现:
其中每个
A,B,C,D
可以被认为是一个方阵(并且对于1x 1矩阵,A’== A)。不幸的是,使用转置只能在需要并行转置最低2x2矩阵的级别上帮助您-ARM 64指令集缺少转置最高级别的指令,即一次64位,在arm-v7上作为
swp d2, d0
完成。反正转置还有另一个迭代公式:它会反复地解压或压缩输入。
在 *octave/matlab语言 * 中,我们将zip运算符定义为1,它取数组
a
的前N/2个元素,并将它们与数组的最后N/2个元素交织。因此,使用intrinsic的完整代码可能如下所示:
在某些架构中,如果有8个额外的寄存器备用(4个用于索引,4个用于输出),也可以使用
vtbl
在这里,
int32x4x4_t input
需要与vreinterpretq_u8_s32(input.val[i])
进行元素转换,然后返回,idx0
的值为0 1 2 3 16 17 18 19 32 33 34 35 48 49 50 51
、idx1 == idx0 + 4
等。在M1或M2上,VTBL似乎是指令级并行化,与例如相反。中度最近的皮层A75(v8.2),其中vtbl花费3 N +1个时钟周期,没有双发出能力。