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/… 你有 AVX512FAVX512VL 吗? @walter,不,只有带有m256的AVX 用内在函数版本更新了我对链接副本的回答。它setr 答案更有效,这里给出了标量位测试。显然用它来获取掩码并使用_mm256_and_ps 申请,因为0.0 & anything0.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 需要置换?

如何将无符号整数加载到 SIMD 中

Intel的AVX2指令集解读

SIMD指令集——一条指令操作多个数,SSE,AVX都是,例如:乘累加,Shuffle等

是否所有支持 AVX2 的 CPU 也支持 SSE4.2 和 AVX?

有/没有 SSE simd 操作的结果是不同的