随机播放 AVX 寄存器中的元素
Posted
技术标签:
【中文标题】随机播放 AVX 寄存器中的元素【英文标题】:Shuffle elements in AVX register 【发布时间】:2017-03-05 12:09:47 【问题描述】:我有一个向量,其双精度值存储在 AVX 寄存器中,其元素为 a0,a1,a2,a3
。现在,我想创建三个新向量(也应该存储为__m256d
变量),比如说 b、c 和 d,包含以下元素:
b = a0,a1,a0,a0
c = a1,a2,a2,a1
d = a2,a3,a3,a2
如何使用 AVX 做到这一点?
【问题讨论】:
您的意思是仅使用 AVX1?如果可以使用AVX2,效率更高:b = _mm256_permute4x64_pd(a, _MM_SHUFFLE(0,1,0,0));
。
【参考方案1】:
看看编译器是如何做到的,使用gcc
向量扩展-march=core-avx2
#include <stdint.h>
typedef double v4df __attribute__((vector_size(32)));
typedef uint64_t v4u64 __attribute__((vector_size(32)));
void foo(v4df a, v4df *b, v4df *c, v4df *d)
*b = __builtin_shuffle(a, (v4u64)0, 1, 0, 0);
*c = __builtin_shuffle(a, (v4u64)1, 2, 2, 1);
*d = __builtin_shuffle(a, (v4u64)2, 3, 3, 2);
gcc-4.8.4 -march=core-avx2 -O3 产生:
vpermpd $4, %ymm0, %ymm1
vmovapd %ymm1, (%rdi)
vpermpd $105, %ymm0, %ymm1
vpermpd $190, %ymm0, %ymm0
vmovapd %ymm1, (%rsi)
vmovapd %ymm0, (%rdx)
vzeroupper
ret
gcc-4.8.4 -march=corei7-avx -O3 产生:
vinsertf128 $1, %xmm0, %ymm0, %ymm1
vpermilpd $2, %ymm1, %ymm1
vmovapd %ymm1, (%rdi)
vperm2f128 $33, %ymm0, %ymm0, %ymm1
vshufpd $9, %ymm1, %ymm0, %ymm1
vmovapd %ymm1, (%rsi)
vperm2f128 $49, %ymm0, %ymm0, %ymm0
vpermilpd $6, %ymm0, %ymm0
vmovapd %ymm0, (%rdx)
vzeroupper
ret
【讨论】:
以上是关于随机播放 AVX 寄存器中的元素的主要内容,如果未能解决你的问题,请参考以下文章
AVX2:AVX 寄存器中 8 位元素的 CountTrailingZeros
如何将 AVX512 寄存器 zmm26 中的 QuadWord 写入 rax 寄存器?
测试 256 位 YMM AVX 寄存器元素是不是等于或小于零的最有效方法