【问题标题】:Conditional SSE/AVX add or zero elements based on compare基于比较的条件 SSE/AVX 添加或零元素
【发布时间】:2018-04-23 13:35:31
【问题描述】:

我有以下__m128 向量:

v_weight

v_entropy

我需要将v_entropy 添加到v_weight 仅当v_weight 中的元素不是0f 时。

显然_mm_add_ps() 无论如何都会添加所有元素。

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

编辑

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

【问题讨论】:

  • SSE/AVX 比较返回一个掩码,您可以使用您的向量。
  • 你知道哪个比较内在函数有掩码吗? _mm_cmp_ps() 是我看到的唯一适用的比较,但它不返回掩码。
  • 我想通了。 _mm_cmpneq_ps_mm_and_ps
  • 它会改变哪个v_weight 应该为零?如果没有,请仅在实际使用 v_weight 之前创建一次 maskv_weight &= mask
  • 是的,它会改变的。

标签: c sse intrinsics avx


【解决方案1】:

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 以使其也可用于整数。)

【讨论】:

  • 您可以使用 _mm_andnot_ps 来避免强制转换(以及某些 CPU 上的旁路延迟可能导致的额外延迟)。还有一个blendv_ps,对于 FP 数据来说是一个更好的选择;即使在 Sandybridge 系列上,混合也有 FP 和整数之间的旁路延迟。
猜你喜欢
  • 1970-01-01
  • 2013-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-16
  • 1970-01-01
  • 2018-01-04
  • 2012-03-09
相关资源
最近更新 更多