从__m256中选择元素子集?

时间:2016-09-08 06:25:16

标签: c++ c sse simd avx

我有一个__m256,用于存储8个浮点数,里面的元素如下:

__m256 v = {0,1,2,3,4,5,6,7};

现在我想得到另一个__m256的值,如:

__m256 dst = {0,1,2,4,5,6,x,x};

x 这意味着我不在乎。

我对SIMD不熟悉,有人可以帮忙吗?或者给我一些提示?

谢谢!

2 个答案:

答案 0 :(得分:3)

您可以使用AVX2内在_mm256_permutevar8x32_ps。它可以帮助您在256位向量内部移动元素。请参阅以下示例:

__m256 a = { 10, 20, 30, 40, 50, 60, 70, 80 };
__m256i k = _mm256_setr_epi32(0, 1, 2, 4, 5, 6, 0, 0);
__m256 b = _mm256_permutevar8x32_ps(a, k);

答案 1 :(得分:2)

您需要一条可在128位通道上运行的指令。不幸的是,大多数AVX / AVX2 shuffle / permute指令只能在256位AVX向量的两个128位通道内运行,但有一些没有这个限制。在这种特殊情况下,您正在寻找的内在因素是_mm256_permutevar8x32_ps

#include <stdio.h>
#include <immintrin.h>

int main(void)
{
    __m256 v0 = _mm256_setr_ps(0, 1, 2, 3, 4, 5, 6, 7);
    __m256i vperm = _mm256_setr_epi32(0, 1, 2, 4, 5, 6, 0, 0);

    __m256 v1 = _mm256_permutevar8x32_ps(v0, vperm);

    float f0[8], f1[8];

    _mm256_storeu_ps(f0, v0);
    _mm256_storeu_ps(f1, v1);

    printf("v0: %g %g %g %g %g %g %g %g\n", f0[0], f0[1], f0[2], f0[3], f0[4], f0[5], f0[6], f0[7]);
    printf("v1: %g %g %g %g %g %g %g %g\n", f1[0], f1[1], f1[2], f1[3], f1[4], f1[5], f1[6], f1[7]);

    return 0;
}

编译和测试:

$ gcc -Wall -mavx2 blackball.c 
$ ./a.out 
v0: 0 1 2 3 4 5 6 7
v1: 0 1 2 4 5 6 0 0