有条件的 SSE/AVX 根据比较添加或归零元素

标签 c sse intrinsics avx

我有以下 __m128 vector :

v_weight

v_entropy

只有当 v_weight 中的元素不为 0f 时,我才需要将 v_entropy 添加到 v_weight

显然 _mm_add_ps() 添加了所有元素。

我可以编译成 AVX,但不能编译成 AVX2。

编辑

我事先知道 v_weight 中有多少元素将为 0(总是有 0 或最后 1、2 或 3 个元素)。如果更简单,我如何将 v_entropy 中的相应元素清零?

最佳答案

cmpeq/cmpgt 指令创建一个掩码,全 1 或全 0。整体流程如下:

auto mask=_mm_cmpeq_ps(_mm_setzero_ps(), w);
mask=_mm_andnot_ps(mask, entropy);
w = _mm_add_ps(w, mask);

其他选项是无论如何都要积累,但使用 blendv 在添加/不添加之间进行选择。

auto w2=_mm_add_ps(e,w);
auto mask=_mm_cmpeq_ps(zero,w);
w=_mm_blendv_ps(w2,w, mask);

第三个选项使用 w+e = 0 的事实,当 w=0 时

 m=(w==0); // make mask as in above
 w+=e; // add
 w&=~m; // revert adding for w==0

(我使用 cmpeq 而不是 cmpneq 以使其也可用于整数。)

关于有条件的 SSE/AVX 根据比较添加或归零元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49982536/

相关文章:

c++11 - x86-SSE指令是否具有自动发布获取指令?

c - 如何访问 SHA 内在?

C 头文件给出错误 "VERTEX has no member ' p'"

c - scanf 字符指针中的字符串

c - 在下面的代码中,如何访问第二个参数?

c - 简单的 C 登录表单问题

assembly - 使先前的内存存储对后续的内存加载可见

c++ - 如何使用内在函数对 double 执行绝对值?

c++ - _InterlockedCompareExchange 文档中 "The sign is ignored"的含义

c - 如何最好地模拟 _mm_slli_si128(128 位位移)的逻辑含义,而不是 _mm_bslli_si128