AVX:“如果不为零,则为 1”
Posted
技术标签:
【中文标题】AVX:“如果不为零,则为 1”【英文标题】:AVX: "to 1 if not zero" 【发布时间】:2020-02-26 13:10:29 【问题描述】:如果 float32 数字数组的值不为零,如何使用 AVX 将它们变为 1?
例如:-0.2134f, -1.23f, -0.0f, 12.0f ...
变成1.0f, 1.0f, 0.0f, 1.0f ...
我认为,我们应该将_mm256_or_ps 与其他指令结合起来,但是如何?
【问题讨论】:
【参考方案1】:我想出的第一个想法是将这些值与 0 进行比较,然后将其与一个满是 1 的寄存器进行与运算:
y = _mm256_and_ps(_mm256_cmp_ps(_mm256_setzero_ps(), x, _CMP_NEQ_OQ), _mm256_set1_ps(1.f));
这会将 x 为 0 的地方的所有 1 与一堆 0 和幸运的是 IEEE 754 零也是整数零。其他值将得到一个浮点 1 与一堆 1 的 AND 运算,因此是一个恒等运算。
【讨论】:
【参考方案2】:可能是vcmpps with a NE predicate,那么带有1.0f
位模式的_mm256_and_ps 是您最好的选择。
一个错误的比较谓词给你一个全零位模式,它也方便地表示0.0f
。
全1 & 1.0f = 1.0f。
总共 2 条单指令。仅当您想要 0.0f 以外的值用于 false 情况时,将比较结果用于变量混合会更好。
【讨论】:
小修正:_mm256_cmpne_ps
不存在。对于 AVX,只有通用的 _mm256_cmp_ps
内在函数将比较函数作为立即值参数。我也没有真正意识到这一点。
@ChrissaysReinstateMonica:哦,是的,谢谢。汇编程序仍然实现像VCMPNEQ_OQPS
这样的助记符,但是是的,英特尔决定只为新的 AVX 谓词创建一个通用的内在函数。当我需要 vcmpps
内在函数时,我总是需要查找它。以上是关于AVX:“如果不为零,则为 1”的主要内容,如果未能解决你的问题,请参考以下文章