【发布时间】:2016-03-19 20:55:16
【问题描述】:
MSVC支持AVX/AVX2指令多年,根据this msdn blog post自动生成fused-multiply-add (FMA)指令。
但以下函数都不能编译为 FMA 指令:
float func1(float x, float y, float z)
{
return x * y + z;
}
float func2(float x, float y, float z)
{
return std::fma(x,y,z);
}
更糟糕的是,std::fma 不是作为单个 FMA 指令实现的,它的执行非常糟糕,比普通的 x * y + z 慢得多(如果实现不依赖于FMA 指令)。
我使用/arch:AVX2 /O2 /Qvec 标志编译。
也用/fp:fast试了一下,没有成功。
那么问题是如何强制MSVC自动发出FMA指令呢?
更新
有一个#pragma fp_contract (on|off),它(看起来)什么都不做。
【问题讨论】:
-
你可能需要使用compiler intrinsics functions。
-
我知道这些内在函数,但我对它们不感兴趣。我希望编译器自动生成指令,就像 GCC 和 Clang 一样。现在是 2016 年。此外,在很多情况下,您无法显式使用这些内在函数,因为 fused-multiply-add 不属于单个操作或函数,它来自多个内联优化表达式。
-
祝你好运。根据我的经验,MS 并不关心编译器的那一部分。即使您使用内部函数,它也会为 FMA 指令生成一些非常糟糕的代码。如果您关心 Windows 上 FMA 的性能,请使用不同的编译器。 (ICC还不错)
-
您是在寻找标量 FMA 还是压缩(矢量)FMA?从您的代码 sn-p (假设给定函数未内联) - MSVS 将无法生成矢量代码。如果 MSVS 只使用 FMA,当桌面上有矢量代码时,我不会感到惊讶。您是否尝试编写简单的数据处理循环,迭代地执行 FMA(确保所有数组都定义在同一个函数中)并使用 MSVS 编译它?
标签: c++ visual-c++ x86 avx fma