我有一个 4x4 字节 block ,我想使用通用硬件进行转置。换句话说,对于字节 A-P,我正在寻找最有效(就指令数量而言)的方式
A B C D
E F G H
I J K L
M N O P
到
A E I M
B F J N
C G K O
D H L P
我们可以假设我有指向 A
、E
、I
和 M
的有效指针内存(这样从 A 读取 32 位将得到包含字节 ABCD
的整数)。
这不是 this question 的拷贝因为大小和数据类型的限制。我的矩阵的每一行都可以放入一个 32 位整数,我正在寻找可以使用通用硬件快速执行转置的答案,类似于 SSE 宏 _MM_TRANSPOSE4_PS
的实现。
最佳答案
您想要适饮性和效率。好吧,你不能两者兼得。你说你想用最少的指令来做到这一点。好吧,使用 x86 指令集中的 pshufb 指令(见下文),仅使用 SSE3 的一条指令就可以做到这一点。
也许 ARM Neon 有类似的东西。如果你想要效率(并且确定你需要它)那么学习硬件。
字节的 _MM_TRANSPOSE4_PS
的 SSE 等价物是使用带有掩码的 _mm_shuffle_epi8
(pshufb 的内在函数)。在主循环之外定义掩码。
//use -msse3 with GCC or /arch:SSE2 with MSVC
#include <stdio.h>
#include <tmmintrin.h> //SSSE3
int main() {
char x[] = {0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,15,16};
__m128i mask = _mm_setr_epi8(0x0,0x04,0x08,0x0c, 0x01,0x05,0x09,0x0d, 0x02,0x06,0x0a,0x0e, 0x03,0x07,0x0b,0x0f);
__m128i v = _mm_loadu_si128((__m128i*)x);
v = _mm_shuffle_epi8(v,mask);
_mm_storeu_si128((__m128i*)x,v);
for(int i=0; i<16; i++) printf("%d ", x[i]); printf("\n");
//output: 0 4 8 12 1 5 9 13 2 6 10 15 3 7 11 16
}
关于c++ - 转置 4x4 字节矩阵的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24816728/