AVX:"to 1 if not zero"
AVX: "to 1 if not zero"
如果 float32 数字数组的值不为零,我如何使用 AVX 将它们的值变为 1?
例如:-0.2134f, -1.23f, -0.0f, 12.0f ...
变成1.0f, 1.0f, 0.0f, 1.0f ...
我想,我们应该将 _mm256_or_ps 与其他一些指令结合起来,但是如何呢?
我想到的第一个想法是将这些值与 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 进行 AND 运算,幸运的是,IEEE 754 零也是一个整数零。其他值将得到一个浮点数 1 与一堆 1 的 ANDed,从而进行恒等运算。
可能 vcmpps with a NE predicate,然后 _mm256_and_ps 和 1.0f
的位模式是你最好的选择。
错误的比较谓词为您提供了一个全零位模式,它也方便地表示 0.0f
。
全一 & 1.0f = 1.0f.
总共 2 个单 uop 指令。只有当你想要 0.0f 以外的东西来处理错误的情况时,使用变量混合的比较结果才会更好。
如果 float32 数字数组的值不为零,我如何使用 AVX 将它们的值变为 1?
例如:-0.2134f, -1.23f, -0.0f, 12.0f ...
变成1.0f, 1.0f, 0.0f, 1.0f ...
我想,我们应该将 _mm256_or_ps 与其他一些指令结合起来,但是如何呢?
我想到的第一个想法是将这些值与 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 进行 AND 运算,幸运的是,IEEE 754 零也是一个整数零。其他值将得到一个浮点数 1 与一堆 1 的 ANDed,从而进行恒等运算。
可能 vcmpps with a NE predicate,然后 _mm256_and_ps 和 1.0f
的位模式是你最好的选择。
错误的比较谓词为您提供了一个全零位模式,它也方便地表示 0.0f
。
全一 & 1.0f = 1.0f.
总共 2 个单 uop 指令。只有当你想要 0.0f 以外的东西来处理错误的情况时,使用变量混合的比较结果才会更好。