首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AVX中的AVX2 VPSHUFB仿真

AVX中的AVX2 VPSHUFB仿真
EN

Stack Overflow用户
提问于 2015-09-11 23:00:01
回答 1查看 3K关注 0票数 7

在AVX中只有128位PSHUFB

代码语言:javascript
复制
VPSHUFB xmm1, xmm2, xmm3/m128

而且只有AVX2拥有整个256位AVX寄存器的完整PSHUFB

代码语言:javascript
复制
VPSHUFB ymm1, ymm2, ymm3/m256

如何使用AVX高效地模拟这个指令?

在这种特殊情况下,源只有8个元素(字节),但这些元素可以在目标的整个32个字节内移动。所以只运行2x PSHUFB就没问题了。

我在VPSHUFB中发现的一个问题是,它将16 (0x10)视为0,只有128个或更高的值被填充为零!(最高位集)是否可以不添加、比较和屏蔽而完成?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-12 05:28:39

正如@MaratDukhan所注意到的,_mm256_shuffle_epi8 (即ymm-s的VPSHUFB )没有执行完整的32字节混叠。对我来说,很遗憾.

这就是为什么要在没有AVX2的情况下模仿它,您可以简单地将每个寄存器分割成两半,每一半进行置换,然后组合在一起:

代码语言:javascript
复制
//AVX only
__m256i _emu_mm256_shuffle_epi8(__m256i reg, __m256i shuf) {
    __m128i reg0 = _mm256_castsi256_si128(reg);
    __m128i reg1 = _mm256_extractf128_si256(reg, 1);
    __m128i shuf0 = _mm256_castsi256_si128(shuf);
    __m128i shuf1 = _mm256_extractf128_si256(shuf, 1);
    __m128i res0 = _mm_shuffle_epi8(reg0, shuf0);
    __m128i res1 = _mm_shuffle_epi8(reg1, shuf1);
    __m256i res = _mm256_setr_m128i(res0, res1);
    return res;
}

如果您真的想要对32字节寄存器进行完全洗牌,可以按照本论文的方法进行。把一半和一半混在一起,然后混合在一起。如果没有AVX2,就会出现这样的情况:

代码语言:javascript
复制
//AVX only
__m256i _emu_mm256_shuffle32_epi8(__m256i reg, __m256i shuf) {
    __m128i reg0 = _mm256_castsi256_si128(reg);
    __m128i reg1 = _mm256_extractf128_si256(reg, 1);
    __m128i shuf0 = _mm256_castsi256_si128(shuf);
    __m128i shuf1 = _mm256_extractf128_si256(shuf, 1);
    __m128i res00 = _mm_shuffle_epi8(reg0, shuf0);
    __m128i res01 = _mm_shuffle_epi8(reg0, shuf1);
    __m128i res10 = _mm_shuffle_epi8(reg1, shuf0);
    __m128i res11 = _mm_shuffle_epi8(reg1, shuf1);
    __m128i res0 = _mm_blendv_epi8(res10, res00, _mm_cmplt_epi8(shuf0, _mm_set1_epi8(16)));
    __m128i res1 = _mm_blendv_epi8(res11, res01, _mm_cmplt_epi8(shuf1, _mm_set1_epi8(16)));
    __m256i res = _mm256_setr_m128i(res0, res1);
    return res;
}

如果您确信只使用了reg的下半部分,那么您可以删除reg1res10res11的行,并删除比较和混合。实际上,如果没有AVX2,坚持使用SSE并使用128位寄存器可能更有效。

一般的32字节改组可以使用AVX2进行显著优化:

代码语言:javascript
复制
//Uses AVX2
__m256i _ext_mm256_shuffle32_epi8(__m256i reg, __m256i shuf) {
    __m256i regAll0 = _mm256_permute2x128_si256(reg, reg, 0x00);
    __m256i regAll1 = _mm256_permute2x128_si256(reg, reg, 0x11);
    __m256i resR0 = _mm256_shuffle_epi8(regAll0, shuf);
    __m256i resR1 = _mm256_shuffle_epi8(regAll1, shuf);
    __m256i res = _mm256_blendv_epi8(resR1, resR0, _mm256_cmpgt_epi8(_mm256_set1_epi8(16), shuf));
    return res;
}

注意事项:代码没有测试!

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32533275

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档