c++ - avx浮点按位逻辑运算的原因是什么?

标签 c++ simd avx avx2

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/

相关文章:

c - Go中的地址对齐

c++ - 如何编写编译器可以优化到 SIMD 比较的代码?

c++ - 在类中访问枚举时出错

c++ - 程序崩溃而没有错误消息

C++ 部分模板特化 :Undeclared identifier error

c++ - 快速将 2 个 double 数组交织成具有 2 个 float 和 1 个 int(循环不变)成员的结构数组,并使用 SIMD double->float 转换?

iphone - 在 iPhone 上使用 ARM SIMD 进行游戏向量/矩阵运算的正确方法是什么?

sum - 使用 AVX 一次性完成 4 个水平 double 求和

assembly - 如何强制 VirtualBox GuestOS CPUID 与 HostOS 匹配?

c++ - 如何获取目标文件中类成员的符号?