c – 在MSVC中自动生成FMA指令

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 z)
{
     return std::fma(x,y,z);
}

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

我用/ arch编译:AVX2 / O2 / Qvec标志.
还尝试用/ fp:快速,没有成功.

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

UPDATE

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

解决方法

MSVC 2015确实为标量操作生成fma指令,但不为向量操作生成(除非您明确使用fma内在函数).

我编译了以下代码

//foo.cpp
float mul_add(float a,float b,float c) {
    return a*b + c;
}

//MSVC cannot handle vectors as function parameters so use const references
__m256 mul_addv(__m256 const &a,__m256 const &b,__m256 const &c) {
    return _mm256_add_ps(_mm256_mul_ps(a,b),c);
}

cl /c /O2 /arch:AVX2 /fp:fast /FA foo.cpp

在MSVC2015中它产生了以下组件

;mul_add
vmovaps xmm3,xmm1
vfmadd213ss xmm3,xmm0,xmm2
vmovaps xmm0,xmm3

;mul_addv
vmovups ymm0,YMMWORD PTR [rcx]
vmulps  ymm1,ymm0,YMMWORD PTR [rdx]
vaddps  ymm0,ymm1,YMMWORD PTR [r8]

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...