SIMD,SSE,AVX - 掩码 8 浮动无符号字符? [复制]
Posted
技术标签:
【中文标题】SIMD,SSE,AVX - 掩码 8 浮动无符号字符? [复制]【英文标题】:SIMD, SSE, AVX - mask 8 floats by unsigned char? [duplicate] 【发布时间】:2019-10-09 22:06:03 【问题描述】:如何通过 unsigned char
变量中的位屏蔽 __m256
变量中的 8 个浮点数? (它们的值在编译过程中是未知的)
__m256 flts = _mm256_set1_ps(5.0f);
unsigned char = 0b10010111;//just for example, but can be any value during runtime
所需的输出将有 flts
包含 5、0、0、5、0、5、5、5
Intel Intrinsics Guide有没有有效的说明?
处理器仅支持最高 AVX 的指令(但不支持 AVX2 或更高版本)
【问题讨论】:
要在运行时屏蔽,您需要将值加载到寄存器中,然后使用您制作的屏蔽对它们执行屏蔽操作(例如“与”操作)。您将无法修改 CPU 在运行时执行的实际指令。 ***.com/questions/36488675/… 你有 AVX512F 和 AVX512VL 吗? @walter,不,只有带有m256
的AVX
用内在函数版本更新了我对链接副本的回答。它比setr
答案更有效,这里给出了标量位测试。显然用它来获取掩码并使用_mm256_and_ps
申请,因为0.0 & anything
是0.0
,即普通SIMD 掩码。
【参考方案1】:
如果你有 AVX512F 和 AVX512VL,你可以使用这个:
auto input = _mm256_set1_ps(5.0f);
__mmask8 mask = 0b10101010;
auto masked = _mm256_maskz_mov_ps(mask,input);
否则,您必须使用按位,例如,当您首先必须找到一种方法将 8 位“解包”为 __m256
的 8 个 32 位字段时
static constexpr int32_t all_mask=int(0xffffffff);
audo tmp = _mm256_setr_epi32(mask&1 ? all_mask:0, mask&2 ? all_mask:0,
mask&4 ? all_mask:0, mask&8 ? all_mask:0,
mask&16? all_mask:0, mask&32 ? all_mask:0,
mask&64? all_mask:0, mask&128? all_mask:0);
auto masked = _mm256_and_ps(tmp,input);
(我可能混淆了_mm256_setr_epi32
和_mm256_set_epi32
。)大概有一种更快的方法可以解开面具,请参阅this answer。
换句话说,在这种情况下,最好不要使用 8 位整数询问掩码,而是直接使用 __m256
或 __m256i
。
【讨论】:
您可以使用 SIMD 而不是_mm_set
/setr
对 movemask 的逆进行很多。我有时间会谷歌。
您的版本在 GCC9.2 中几乎是性能灾难(所有标量,然后将每个掩码分别插入到向量中),而 clang9.0 也好不到哪里去。 godbolt.org/z/m7elLc (虽然 clang 确实提出了一些有趣的东西,比如用 SIMD 整数乘以大的单位常量的位图的一半,并使用 vpsrad
的一半)。不过,这些比使用 256 位 AND + FP 比较来检查匹配的 FP 位模式要差得多。以上是关于SIMD,SSE,AVX - 掩码 8 浮动无符号字符? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
SIMD指令集——一条指令操作多个数,SSE,AVX都是,例如:乘累加,Shuffle等