_mm256_shuffle_epi 意外 __256i 向量

unexpected _mm256_shuffle_epi with __256i vectors

我已经看到 this great answer 使用 __m128i 进行图像转换,我想我会尝试使用 AVX2 看看我是否可以更快地获得它。任务是获取输入的 RGB 图像并将其转换为 RGBA(注意另一个问题是 BGRA,但这并没有太大的区别...)。

如果需要,我可以包含更多代码,但是这些东西变得非常冗长,我被困在看似非常简单的事情上。假设对于这段代码,所有内容都是 32 字节对齐的,使用 -mavx2 编译,等等

给定输入 uint8_t *source RGB 和输出 uint8_t *destination RGBA,它是这样的(只是试图用条纹填充图像的四分之一 [因为这是矢量土地])。

#include <immintrin.h>
__m256i *src = (__m256i *) source;
__m256i *dest = (__m256i *) destination;

// for this particular image
unsigned width = 640;
unsigned height = 480;
unsigned unroll_N = (width * height) / 32;
for(unsigned idx = 0; idx < unroll_N; ++idx) {
    // Load first portion and fill all of dest[0]
    __m256i src_0 = src[0];
    __m256i tmp_0 = _mm256_shuffle_epi8(src_0,
        _mm256_set_epi8(
            0x80, 23, 22, 21,// A07 B07 G07 R07
            0x80, 20, 19, 18,// A06 B06 G06 R06
            0x80, 17, 16, 15,// A05 B05 G05 R05
            0x80, 14, 13, 12,// A04 B04 G04 R04
            0x80, 11, 10,  9,// A03 B03 G03 R03
            0x80,  8,  7,  6,// A02 B02 G02 R02
            0x80,  5,  4,  3,// A01 B01 G01 R01
            0x80,  2,  1,  0 // A00 B00 G00 R00
        )
    );

    dest[0] = tmp_0;

    // move the input / output pointers forward
    src  += 3;
    dest += 4;
}// end for

这根本行不通。每个 "quarter".

中都出现了条纹

我在这里错过了什么?有没有可能我 运行 超出了寄存器之类的?我会对此感到非常惊讶...

正在使用

_mm256_set_epi8(
    // 0x80, 23, 22, 21,// A07 B07 G07 R07
    // 0x80, 20, 19, 18,// A06 B06 G06 R06
    // 0x80, 17, 16, 15,// A05 B05 G05 R05
    // 0x80, 14, 13, 12,// A04 B04 G04 R04
    0x80, 0x80, 0x80, 0x80,
    0x80, 0x80, 0x80, 0x80,
    0x80, 0x80, 0x80, 0x80,
    0x80, 0x80, 0x80, 0x80,
    0x80, 11, 10,  9,// A03 B03 G03 R03
    0x80,  8,  7,  6,// A02 B02 G02 R02
    0x80,  5,  4,  3,// A01 B01 G01 R01
    0x80,  2,  1,  0 // A00 B00 G00 R00
)

_mm256_shuffle_epi8 的工作方式类似于并排 _mm_shuffle_epi8 的两倍,而不是更有用(但可能延迟更高)的全角洗牌,可以将任何字节放在任何地方。这是来自 www.officedaytime.com/simd512e 的图表:

AVX512VBMI 具有新的字节粒度洗牌,例如 vpermb 可以跨通道,但当前的处理器尚不支持该指令集扩展。