AVX 允许在 float 据类型 __m256 和 __m256d 上进行按位逻辑运算,例如和/或。
但是,C++ 不允许对 float 和 double 进行按位运算,这是合理的。如果我是对的,则不能保证 float 的内部表示,编译器是否会使用 IEEE754,因此程序员无法确定 float 的位会是什么样子。
考虑这个例子:
#include <immintrin.h>
#include <iostream>
#include <limits>
#include <cassert>
int main() {
float x[8] = {1,2,3,4,5,6,7,8};
float mask[8] = {-1,0,0,-1,0,-1,0,0};
float x_masked[8];
assert(std::numeric_limits<float>::is_iec559);
__m256 x_ = _mm256_load_ps(x);
__m256 mask_ = _mm256_load_ps(mask);
__m256 x_masked_ = _mm256_and_ps(x_,mask_);
_mm256_store_ps(x_masked,x_masked_);
for(int i = 0; i < 8; i++)
std::cout << x_masked[i] << " ";
return 0;
}
假设使用 IEEE754,因为 -1 的表示是 0xffffffff,我希望输出是
1,0,0,4,0,6,0,0
虽然是这样
1 0 0 1.17549e-38 0 1.17549e-38 0 0
因此我对内部表示的假设可能是错误的(或者我犯了一些愚蠢的错误)。
所以问题是:有没有一种方法可以让我在逻辑上使用 float 并确保结果有意义这一事实?
最佳答案
如果您使用的是 AVX 内在函数,那么您就知道您使用的是 IEEE754 float ,因为这就是 AVX 所做的。
一些对 float 有意义的按位运算是
- 选择,如 Jens 的回答,尽管从 SSE4.1 开始,我们有
blendvps
及其亲属在一条指令中完成此操作 - 绝对值(屏蔽符号)
- 求反(与 -0.0f 异或)
- 转移标志
- 提取指数(罕见)
主要是为了操纵符号,或者有选择地将整个 float 清零,而不是为了处理指数或尾数的个别位——你可以做到,但很少有用。
关于c++ - avx浮点按位逻辑运算的原因是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24943521/