在整个YMM寄存器上执行旋转操作的最快方法是什么,只有在运行时才知道?
所述旋转已知为64位的倍数。
发布于 2013-10-06 03:46:01
使用AVX2,您可以使用_mm256_permutevar8x32_epi32。伪代码(未经测试,常量可能出错):
static inline __m256i rotate(__m256i x, unsigned n) {
static const __m256i rotspec[4] = {
_mm256_set_epi32(0, 1, 2, 3, 4, 5, 6, 7),
_mm256_set_epi32(6, 7, 0, 1, 2, 3, 4, 5),
_mm256_set_epi32(4, 5, 6, 7, 0, 1, 2, 3),
_mm256_set_epi32(2, 3, 4, 5, 6, 7, 0, 1)
};
return _mm256_permutevar8x32_epi32(x, rotspec[n]);
}发布于 2013-10-23 04:40:07
您可以使用AVX旋转,如下所示。假设您的输入是x
__m256d t0 = _mm256_permute_pd(x, 0x05); // [x2 x3 x0 x1]
__m256d t1 = _mm256_permute2f128_pd(t0, t0, 0x01); // [x0 x1 x2 x3]
__m256d y = _mm256_blend_pd(t0, t1, 0x0a); // [x0 x3 x2 x1]结果在y中。通过倒置混合面罩,您可以向左旋转:
__m256d t0 = _mm256_permute_pd(x, 0x05); // [x2 x3 x0 x1]
__m256d t1 = _mm256_permute2f128_pd(t0, t0, 0x01); // [x0 x1 x2 x3]
__m256d y = _mm256_blend_pd(t0, t1, 0x05); // [x2 x1 x0 x3]发布于 2013-10-28 01:20:47
如果您仅限于AVX指令,您仍然可以使用条件混合指令(VBLENDVPD)来选择正确的旋转而不使用开关。这可能会更快,特别是当情况难以预测的时候。
充分执行正确的轮调(经测试):
// rotate packed double vector right by n
__m256d rotate_pd_right(__m256d x, int n) {
__m128i c = _mm_cvtsi32_si128(n);
__m128i cc = _mm_unpacklo_epi64(c,c);
// create blend masks (highest bit)
__m128d half_low = _mm_castsi128_pd(_mm_slli_epi64(cc, 63));
__m128d swap_low = _mm_castsi128_pd(_mm_slli_epi64(cc, 62));
__m256d half = _mm256_insertf128_pd(_mm256_castpd128_pd256(half_low), half_low, 1);
__m256d swap = _mm256_insertf128_pd(_mm256_castpd128_pd256(swap_low), swap_low, 1);
// compute rotations
__m256d t0 = _mm256_permute_pd(x, 0x05); // [2 3 0 1]
__m256d t1 = _mm256_permute2f128_pd(t0, t0, 0x01); // [1 0 2 3]
__m256d y0 = x; // [3 2 1 0]
__m256d y1 = _mm256_blend_pd(t0, t1, 0x0a); // [0 3 2 1]
__m256d y2 = _mm256_permute2f128_pd(x, x, 0x01); // [1 0 3 2]
__m256d y3 = _mm256_blend_pd(t0, t1, 0x05); // [2 1 0 3]
// select correct rotation
__m256d y01 = _mm256_blendv_pd(y0, y1, half);
__m256d y23 = _mm256_blendv_pd(y2, y3, half);
__m256d yn = _mm256_blendv_pd(y01, y23, swap);
return yn;
}左旋可以简单地作为
__m256d rotate_pd_left(__m256d x, int n) {
return rotate_pd_right(x, -n);
}https://stackoverflow.com/questions/19205026
复制相似问题