C++ 编译器为 AVX SIMD 代码给出不同的结果

问题描述 投票:0回答:0

我正在研究如何检测 SIMD 寄存器的哪些通道中的浮点数是 +/- 无穷大或 +/- 南。在运行时看到一些奇怪的行为后,我决定将东西扔到 Godbolt 中进行调查,结果很奇怪: https://godbolt.org/z/TdnrK8rqd

#include <immintrin.h>
#include <cstdio>
#include <limits>
#include <cstdint>

static constexpr float inf = std::numeric_limits<float>::infinity();
static constexpr float qnan = std::numeric_limits<float>::quiet_NaN();
static constexpr float snan = std::numeric_limits<float>::signaling_NaN();

int main() {
    __m256 a = _mm256_setr_ps(0.0f, 1.0f, inf, -inf, qnan, -qnan, snan, -snan);

    __m256 mask = _mm256_sub_ps(a, a);

    // Extract masks as integers 
    int mask_bits = _mm256_movemask_ps(mask);

    std::printf("Mask for INFINITY or NaN: 0x%x\n", mask_bits);

    #define PRINT_ALL
    #ifdef PRINT_ALL
    float data_field[8];
    float mask_field[8];
    _mm256_storeu_ps(data_field, a);
    _mm256_storeu_ps(mask_field, mask);
    for (int i = 0; i < 8; ++i) {
        std::printf("isfinite(%f) = %x = %f\n", data_field[i], ((int32_t*)(char*)mask_field)[i], mask_field[i]);
    }
    #endif
    
    return 0;
}

编译器给出不同的结果,甚至根据优化级别产生不同的结果。一些编译器只是在编译时使用(损坏的?)推理完全执行代码,并且它全部编译为一些硬编码的打印语句,而没有在运行时进行实际计算。更改优化级别会导致某些编译器触发此(不正确?)优化?

此外,我似乎设法通过手动打印所有结果(

PRINT_ALL
选项)来影响发生的事情。

打印出来的口罩差别很大:

  • 没有
    PRINT_ALL
    • 海湾合作委员会 13.1
      -O0
      :0xac
    • 海湾合作委员会 13.1
      -O1
      :0x5c
    • Clang 16.0.0
      -O0
      :0xac
    • 铛 16.0.0
      -O1
      :0xa0
    • ICX 2022.2.1
      -O0
      :0xac
    • ICX 2022.2.1
      -O1
      :0xa0
  • PRINT_ALL
    • 海湾合作委员会 13.1
      -O0
      :0xac
    • 海湾合作委员会 13.1
      -O1
      :0xac
    • Clang 16.0.0
      -O0
      :0xac
    • 铛 16.0.0
      -O1
      :0xa0
    • ICX 2022.2.1
      -O0
      :0xac
    • ICX 2022.2.1
      -O1
      :0xa0

ICX 和 clang 似乎彼此一致,但根据优化级别的不同,结果仍然不同。我猜 0xac 是正确的结果,因为这就是

-O0
中发生的事情,所有结果实际上都是由 CPU 在运行时计算的,编译器没有试图变得聪明。

最重要的是,我的问题是,这是根据我不知道的某些规则的“预期行为”,还是我在三种不同的编译器(GCC、Clang 和 ICX)中发现了错误? (我无法测试 MSVC,因为 Goldbolt 不支持执行这些构建的代码。)

c++ compiler-optimization simd compiler-bug
© www.soinside.com 2019 - 2024. All rights reserved.