AVX寄存器中的随机元素

时间:2017-03-05 12:09:48

标签: c x86 simd avx

我有一个带有双精度数的向量存储在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执行此操作?

1 个答案:

答案 0 :(得分:5)

使用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