【问题标题】:Are there compatibility issues with clang-cl and arch:avx2?clang-cl 和 arch:avx2 是否存在兼容性问题?
【发布时间】:2020-06-21 01:47:31
【问题描述】:

我使用的是 Windows 10、Visual Studio 2019、平台:x64,并且在单文件 Visual Studio 解决方案中有以下测试脚本:

#include <iostream>
#include <intrin.h>
using namespace std;

int main() {
    unsigned __int64 mask = 0x0fffffffffffffff; //1152921504606846975;
    unsigned long index;

    _BitScanReverse64(&index, mask);
    if (index != 59) {
        cout << "Fails!" << endl;
        return EXIT_FAILURE;
    }
    else {
        cout << "Success!" << endl;
        return EXIT_SUCCESS;
    }
}

在我的属性解决方案中,我将“启用增强指令集”设置为“高级矢量扩展 2 (/arch:AVX2)”。 使用 msvc 编译时(将“平台工具集”设置为“Visual Studio 2019 (v142)”),代码返回 EXIT_SUCCESS,但是使用 clang-cl 编译时(将“平台工具集”设置为“LLVM (clang-cl)”)我得到了EXIT_FAILURE。在调试 clang-cl 运行时,index 的值是 4,应该是 59。这表明 clang-cl 正在读取 MSVC 的相反方向的位。

当我将“启用增强指令集”设置为“未设置”时,情况并非如此。在这种情况下,MSVC 和 clang-cl 都返回 EXIT_SUCCESS。

在所有情况下,所有 dll 都已加载并显示在“调试输出”窗口中来自 C:\Windows\System32###.dll。

有人理解这种行为吗?如果有任何见解,我将不胜感激。

编辑:我之前没有提到:我用 IntelCore i7-3930K CPU @3.20GHz 编译了这个。

【问题讨论】:

    标签: visual-c++ x86-64 avx2 clang-cl


    【解决方案1】:

    得到 4 而不是 59 听起来像是 clang 将 _BitScanReverse64 实现为 63 - lzcnt。实际的bsr 在 AMD 上很慢,所以是的,编译器想要编译不同指令固有的 BSR 是有原因的。

    但是您在实际上不支持 BMI 的计算机上运行可执行文件,因此 lzcnt 解码为 rep bsr = bsr,给出前导零计数而不是位- 最高设置位的索引。

    AFAIK,所有具有 AVX2 的 CPU 也具有 BMI。如果您的 CPU 没有这个功能,您不应该期望使用 /arch:AVX2 构建的可执行文件能够在您的 CPU 上正确运行。在这种情况下,故障模式不是非法指令,而是 lzcntbsr 运行。

    MSVC 通常不会优化内在函数,显然包括这种情况,所以它只是直接使用bsr


    更新:i7-3930K 是 SandyBridge-E。它没有 AVX2,因此可以解释您的结果。

    当您告诉它在非 AVX2 计算机上构建 AVX2 可执行文件时,clang-cl 不会出错。其用例是在一台机器上编译以创建可执行文件以在不同机器上运行。

    它也不会为您将 CPUID 检查代码添加到您的可执行文件中。如果您愿意,请自己编写。这是 C++,它不会牵你的手。


    目标 CPU 选项

    MSVC 风格的/arch 选项比普通的 GCC/clang 风格更受限制。 SSE4.1 等不同级别的 SSE 都没有;它直接跳转到 AVX。

    此外,/arch:AVX2 显然意味着 BMI1/2,即使它们是具有不同 CPUID 功能位的不同指令集。例如,在内核代码中,您可能需要整数 BMI 指令,而不是涉及 XMM/YMM 寄存器的 SIMD 指令。

    clang -O3 -mavx2不会也启用-mbmi。你通常会想要这样,但如果你也没有启用 BMI,那么使用bsr 会卡住clang。 (对于英特尔 CPU,这实际上比 63-lzcnt 更好)。我认为 MSVC 的 /arch:AVX2 类似于 -march=haswell,如果它也启用 FMA 指令的话。

    MSVC 中没有任何支持优化二进制文件以在您构建它们的计算机上运行。这是有道理的,它是为软件开发的闭源二进制分发模型而设计的。

    但 GCC 和 clang 有 -march=native 来启用您的计算机支持的所有指令集。同样重要的是,设置适合您计算机的 调整 选项。例如不用担心在 AMD CPU 或旧版 Intel 上编写代码会很慢,只需编写适合 您的 CPU 的 asm。

    TL:DR:clang-cl 中的 CPU 选择选项非常粗略,将非 SIMD 扩展与某种级别的 AVX 混为一谈。这就是为什么 /arch:AVX2 启用整数 BMI 扩展,而 clang -mavx2 没有。

    【讨论】:

    • 糟糕,我编辑了我的帖子以包含我的 CPU 信息。也许它只是没有 avx2 支持?我很惊讶它仍然试图编译而不是抛出错误!谢谢,这真的很有帮助!
    • @polortiz40:那是 Sandybridge,2 代太老了,无法使用 BMI1/2 或 AVX2/FMA。您只有 AVX1。查看我的更新。
    • 这是一个很好的答案。太感谢了!我想我应该在尝试使用它们之前检查我的 cpu 是否可以支持架构
    猜你喜欢
    • 2015-05-05
    • 1970-01-01
    • 1970-01-01
    • 2022-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-02
    • 1970-01-01
    相关资源
    最近更新 更多