在MSVC中自动生成FMA指令

pla*_*cel 9 c++ x86 avx visual-c++ fma

MSVC多年来一直支持AVX/AVX2指令,根据这篇msdn博客文章,它可以自动生成融合乘法加法(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);
}
Run Code Online (Sandbox Code Playgroud)

更糟糕的是,std :: fma没有实现为单个FMA指令,它执行速度非常快,比平原慢得多x * y + z(如果实现不依赖于FMA指令,则预期std :: fma的性能很差).

我用/arch:AVX2 /O2 /Qvec旗帜编译.也尝试过/fp:fast,没有成功.

所以问题是MSVC如何被迫自动发出FMA指令?

UPDATE

有一个#pragma fp_contract (on|off),(看起来像)什么都不做.

pla*_*cel 4

我解决了这个长期存在的问题。

事实证明,flags /fp:fast/arch:AVX2/O1(或以上/O1)不足以让 Visual Studio 2015 模式在 32 位模式下发出 FMA 指令。您还需要使用 flag 打开“整个程序优化”/GL

然后Visual Studio 2015将生成一条FMAvfmadd213ss指令

float func1(float x, float y, float z)
{
    return x * y + z;
}
Run Code Online (Sandbox Code Playgroud)

关于std::fma,我在 Microsoft Connect 上打开了一个错误。他们确认了无法编译为 FMA 指令的行为std::fma,因为编译器不会将其视为内在函数。根据他们的回应,它将在未来的更新中修复,以获得尽可能最好的代码生成。