改进AVX中的非水平分配

时间:2017-04-06 04:21:46

标签: c++ x86 simd avx

所以我在处理AVX代码时遇到了另一个问题。我有一个案例,我有4个ymm寄存器需要垂直分割到4个其他ymm寄存器

(即ymm0(ABCD) - > ymm4(A ...),ymm5(B ...),ymm6(C ...),ymm7(D ...))。

以下是一个例子:

// a, b, c, d are __m256 structs with [] operators to access xyzw
__m256d A = _mm256_setr_pd(a[0], b[0], c[0], d[0]);
__m256d B = _mm256_setr_pd(a[1], b[1], c[1], d[1]);
__m256d C = _mm256_setr_pd(a[2], b[2], c[2], d[2]);
__m256d D = _mm256_setr_pd(a[3], b[3], c[3], d[3]);

1 个答案:

答案 0 :(得分:1)

只要把保罗的评论写成答案:

我的问题是如何使用他提供的链接在AVX中轻松完成矩阵转置。

以下是我在这里遇到的人的实施情况:

void Transpose(__m256d* A, __m256d* T)
{
    __m256d t0 = _mm256_shuffle_pd(A[0], A[1], 0b0000);
    __m256d t1 = _mm256_shuffle_pd(A[0], A[1], 0b1111);
    __m256d t2 = _mm256_shuffle_pd(A[2], A[3], 0b0000);
    __m256d t3 = _mm256_shuffle_pd(A[2], A[3], 0b1111);
    T[0] = _mm256_permute2f128_pd(t0, t2, 0b0100000);
    T[1] = _mm256_permute2f128_pd(t1, t3, 0b0100000);
    T[2] = _mm256_permute2f128_pd(t0, t2, 0b0110001);
    T[3] = _mm256_permute2f128_pd(t1, t3, 0b0110001);
}

与我之前的尝试相比,此功能在完全优化时减少了大约一半的指令数