【问题标题】:Preventing GCC from automatically using AVX and FMA instructions when compiled with -mavx and -mfma使用 -mavx 和 -mfma 编译时防止 GCC 自动使用 AVX 和 FMA 指令
【发布时间】:2013-09-22 23:26:46
【问题描述】:

如何使用 AVX 和 FMA 指令禁用自动矢量化?我仍然希望编译器自动使用 SSE 和 SSE2,而不是 FMA 和 AVX。

我使用 AVX 的代码会检查其可用性,但 GCC 在自动矢量化时不会这样做。因此,如果我使用 -mfma 编译并在 Haswell 之前的任何 CPU 上运行代码,我会得到 SIGILL。如何解决这个问题?

【问题讨论】:

  • 你想要的是一个 CPU 调度器。将带有-msse2 的代码编译到一个目标文件中,将-mfma 编译到另一个目标文件中,然后创建一个调度程序,询问CPUID 哪些硬件可用,并将函数指针设置为指向SSE2 或AVX/FMA 版本stackoverflow.com/questions/23676426/…
  • @Zboson:是的,我就是这么做的。让它成为一个答案,我会接受。
  • 最近的 gcc 允许您在没有 -mfma 或 -mavx 的情况下使用内部函数。您还可以指定每个函数的目标。

标签: c++ gcc vectorization avx fma


【解决方案1】:

您要做的是为您所针对的每个指令集编译不同的目标文件。然后创建一个 CPU 调度程序,它向 CPUID 询问可用的指令集,然后跳转到相应版本的函数。

我已经在几个不同的问题和答案中描述了这一点

【讨论】:

    【解决方案2】:

    您需要将使用 AVX 的代码分离到一个单独的编译单元(换句话说,一个单独的 .cpp 文件)中,并仅使用 -mfma 或您想要的任何选项编译该代码。通常,gcc 将使用-march=native,因此它将为“您的处理器”编译,如果您想要通用代码,则需要使用-march=x86_64-march=core2,或类似的东西。

    【讨论】:

    • 那么如果我有一个使用 AVX 的模板类(所有代码都在头文件中)我有麻烦了吗?
    • 是的,它必须写得非常好,以避免每次调用其中一个函数时检查是否有 AVX 会受到惩罚。你真的对它进行了基准测试吗?
    • 我已经对它进行了基准测试,与 SSE2 相比,加速比很小,但它就在那里。当然,我不会每次都调用cpuid,只有在启动时调用一次。
    • 您确定没有单独的选项来禁用自动矢量化吗?
    • 我确信gcc 会根据它认为最好的方式选择它认为适用于您正在编译的架构的“任何”指令。因此,如果有一个聪明的指令来解决特定的结构,它可能会使用 AVX 指令。即使您当前的版本没有,也没有什么可以说版本current + 0.0.1 没有做某种改进。
    猜你喜欢
    • 1970-01-01
    • 2017-05-08
    • 2010-12-31
    • 2013-04-15
    • 1970-01-01
    相关资源
    最近更新 更多