改进 AVX 中的非水平分配
Improve non-horizontal assignment in 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]);
只是将 Paul 的评论放入答案中:
我的问题是关于如何进行矩阵转置,这在 AVX 中很容易完成,如他提供的 link 所示。
对于遇到这里的人,这是我的实现:
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);
}
与我之前的尝试相比,此函数在全面优化时将指令数量减少了大约一半
所以我在处理 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]);
只是将 Paul 的评论放入答案中:
我的问题是关于如何进行矩阵转置,这在 AVX 中很容易完成,如他提供的 link 所示。
对于遇到这里的人,这是我的实现:
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);
}
与我之前的尝试相比,此函数在全面优化时将指令数量减少了大约一半