C++ SSE和AVX的通道/通道洗牌?

C++ SSE和AVX的通道/通道洗牌?,c++,c,vectorization,sse,avx,C++,C,Vectorization,Sse,Avx,什么SSE/AVX指令将通道从a洗牌为b和c? float4a={data[0],data[1],data[2],data[3]}; float4b={data[1],data[2],data[3],data[0]};//车道左移 float4c={data[3],data[0],data[1],data[2]};//车道右移 float8a={data[0],data[1],data[2],data[3], 数据[4],数据[5],数据[6],数据[7]}; float8b={data[1],

什么SSE/AVX指令将通道从
a
洗牌为
b
c

float4a={data[0],data[1],data[2],data[3]};
float4b={data[1],data[2],data[3],data[0]};//车道左移
float4c={data[3],data[0],data[1],data[2]};//车道右移
float8a={data[0],data[1],data[2],data[3],
数据[4],数据[5],数据[6],数据[7]};
float8b={data[1],data[2],data[3],data[4],
数据[5],数据[6],数据[7],数据[0]};//车道左移
float8 c={data[7],data[0],data[1],data[2],
数据[3],数据[4],数据[5],数据[6]};//车道右移
背景:

我有一个算法,需要它的邻居点的值;这意味着我目前正在混合对齐负载和未对齐负载:

(
板[行+1][列]//对齐
+板[第1行][第列]//对齐
+板[行][列+1]//未对齐
+板[行][列-1]//未对齐
+(4*板[行][列]//对齐
) / 8;
这里是苏格兰和南方能源公司:

\uuum128底部=\umm\uload\ups(&from[row-1][column]);
__m128左=_mm_loadu_ps(&from[行][列-1]);
__m128中间=_mm_load_ps(&from[行][列]);
__m128右=_mm_loadu_ps(&from[行][列+1]);
__m128顶部=_mm_载荷_ps&来自[行+1][列];
(顶部+底部+左侧+右侧+毫米设置1毫米ps(4.0f)*中间)*毫米设置1毫米ps(0.125f);
我意识到current和left或right中的值只相差一个值。因此,我有一个想法,不必做2次未对齐的加载,我可以洗牌车道,然后插入一个不同的值。我需要检查指令的延迟/吞吐量,看看是否会更快,但我不熟悉这些类型的SSE/AVX指令。

在最近的英特尔CPU(Core i7等)上,未对齐的负载是一种合理的方法,但在旧CPU上,它相对昂贵。另一种方法是使用
\u mm\u aligner\u epi8
PALIGNR
)-通常沿一行迭代并保持3个连续向量-每次迭代后,将这些向量沿一个向量洗牌,然后加载一个新向量,因此每次迭代只有一个加载

__m128 va = _mm_setzero_ps();
__m128 vb = _mm_load_ps(&from[row][0]);
for (col = 0; col < N; col += 4)
{
    __m128 vc = _mm_load_ps(&from[row][col + 4]);

    __m128 centre = vb;
    __m128 left = (__m128)_mm_alignr_epi8((__m128i)va, (__m128i)vb, sizeof(float));
    __m128 right = (__m128)_mm_alignr_epi8((__m128i)vb, (__m128i)vc, 3 * sizeof(float));

    // do stuff ...

    va = vb;  // shuffle vectors along
    vb = vc;
}
\uuum128 va=\umm\usetzero\ups();
__m128 vb=_mm_load_ps(&from[row][0]);
对于(列=0;列
由于128位通道的限制,AVX有点棘手-您最好还是坚持使用未对齐的负载