Matrix 使用SIMD内部函数的高效行-列转换

Matrix 使用SIMD内部函数的高效行-列转换,matrix,x86,sse,simd,avx,Matrix,X86,Sse,Simd,Avx,我是SIMD编程的初学者。我想按如下方式处理我的数据: __m128i a = {a1, a2, a3, a4} __m128i b = {b1, b2, b3, b4} __m128i c = {c1, c2, c3, c4} __m128i d = {d1, d2, d3, d4} 假设我有4个simd变量(\uuu m128i),数据如下: __m128i a = {a1, a2, a3, a4} __m128i b = {b1, b2, b3, b4} __m128i c = {c1,

我是SIMD编程的初学者。我想按如下方式处理我的数据:

__m128i a = {a1, a2, a3, a4}
__m128i b = {b1, b2, b3, b4}
__m128i c = {c1, c2, c3, c4}
__m128i d = {d1, d2, d3, d4}
假设我有4个simd变量(
\uuu m128i
),数据如下:

__m128i a = {a1, a2, a3, a4}
__m128i b = {b1, b2, b3, b4}
__m128i c = {c1, c2, c3, c4}
__m128i d = {d1, d2, d3, d4}
现在我想把席初始化如下:

__m128i x1 = {a1, b1, c1, d1}
__m128i x2 = {a2, b2, c2, d2}
__m128i x3 = {a3, b3, c3, d3}
__m128i x4 = {a4, b4, c4, d4}

有人能告诉我如何才能有效地完成这项工作吗?

我假设您的问题中有一个输入错误,您实际上想进行4x4转置。如果是这样,您可以使用8条指令进行4x4转置,如下所示:

#包括“emmintrin.h”
内联无效转置4(
__m128i&v0,//a1、a2、a3、a4=>a1、b1、c1、d1
__m128i&v1,//b1,b2,b3,b4=>a2,b2,c2,d2
__m128i&v2,//c1,c2,c3,c4=>a3,b3,c3,d3
__m128i和v3)//d1、d2、d3、d4=>a4、b4、c4、d4
{
__m128i w0=_mm_Unplo_epi32(v0,v1);
__m128i w1=_mm_Unpachi_epi32(v0,v1);
__m128i w2=_mm_unplo_epi32(v2,v3);
__m128iw3=_-mm_-unpachi_-epi32(v2,v3);
v0=_mm_unplo_epi64(w0,w2);
v1=mm_epi64(w0,w2);
v2=毫米epi64(w1,w3);
v3=毫米/毫米/毫米/毫米epi64(w1,w3);
}
演示:

//
//Transpose_4_4.cpp
//
#包括
#包括
内联无效转置4(
__m128i&v0,//a1、a2、a3、a4=>a1、b1、c1、d1
__m128i&v1,//b1,b2,b3,b4=>a2,b2,c2,d2
__m128i&v2,//c1,c2,c3,c4=>a3,b3,c3,d3
__m128i和v3)//d1、d2、d3、d4=>a4、b4、c4、d4
{
__m128i w0=_mm_Unplo_epi32(v0,v1);
__m128i w1=_mm_Unpachi_epi32(v0,v1);
__m128i w2=_mm_unplo_epi32(v2,v3);
__m128iw3=_-mm_-unpachi_-epi32(v2,v3);
v0=_mm_unplo_epi64(w0,w2);
v1=mm_epi64(w0,w2);
v2=毫米epi64(w1,w3);
v3=毫米/毫米/毫米/毫米epi64(w1,w3);
}
内部主(空)
{
int32_t buff[4][4]___属性(对齐(16));
int i,j;
int k=0;
//初始增益
对于(i=0;i<4;++i)
{
对于(j=0;j<4;++j)
{
buff[i][j]=k++;
}
}
//打印增益
printf(“\n前:\n”);
对于(i=0;i<4;++i)
{
对于(j=0;j<4;++j)
{
printf(“%4d”,浅黄色[i][j]);
}
printf(“\n”);
}
//转置
转置_4_4(*(_m128i*)buff[0]、*(_m128i*)buff[1]、*(_m128i*)buff[2]、*(_m128i*)buff[3]);
//打印增益
printf(“\n之后:\n”);
对于(i=0;i<4;++i)
{
对于(j=0;j<4;++j)
{
printf(“%4d”,浅黄色[i][j]);
}
printf(“\n”);
}
返回0;
}
编译并运行:

$ g++ -Wall -msse3 transpose_4_4.cpp && ./a.out 

BEFORE:
   0   1   2   3
   4   5   6   7
   8   9  10  11
  12  13  14  15

AFTER:
   0   4   8  12
   1   5   9  13
   2   6  10  14
   3   7  11  15
$ 

@孙卓石:你的编辑不正确-上面的代码已经过测试,给出了正确的结果。是的,你是对的。很抱歉没有仔细测试@保罗R