意想不到_mm256_shuffle_epi与__256i矢量(unexpected _mm256_

2019-10-28 12:39发布

我看到了这个伟大的答案上使用图像转换__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

这甚至不实际工作。 有条纹显示在每个“季度”起来。

  • 我的理解是0x80应该被用来创建0x00的面具
    • 它并不真正甚至无论什么值到达那里(它的alpha通道,在它得到真正的代码OR “以D 0xff像挂的答案)。
  • 这在某种程度上似乎与行0407 ,如果我让他们所有, 0x80只留下00 - 03不一致消失。
    • 但当然,我不是复制一切,我需要。

我缺少的是在这里吗? 就像是有可能我跑出去寄存器或什么的? 我会通过非常惊讶......

运用

_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
)

Answer 1:

_mm256_shuffle_epi8就像一两次_mm_shuffle_epi8并排侧,而不是像一个更有用(但可能更高的延迟),全宽洗牌,可以在任何地方把任何字节。 下面是从图www.officedaytime.com/simd512e :

AVX512VBMI有新的字节粒度洗牌如vpermb能穿越车道,但目前的处理器不支持指令集扩展呢。



文章来源: unexpected _mm256_shuffle_epi with __256i vectors