首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在MSVC中自动生成FMA指令

在MSVC中自动生成FMA指令
EN

Stack Overflow用户
提问于 2015-12-14 11:32:25
回答 2查看 3.6K关注 0票数 10

MSVC多年来一直支持AVX/AVX 2指令,根据这篇msdn博客文章,它可以自动生成融合-乘-加(FMA)指令。

然而,以下两种功能都不符合FMA指令:

代码语言:javascript
复制
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);
}

更糟糕的是,FMA不是作为一个FMA指令实现的,它的执行速度比普通的x * y + z慢得多(如果实现不依赖FMA指令,那么std::fma的性能会很差)。

我使用/arch:AVX2 /O2 /Qvec标志进行编译。也在/fp:fast上尝试过,但没有成功。

因此,问题是MSVC如何被迫自动发出FMA指令?

更新

有一个#pragma fp_contract (on|off),它看起来什么也不做。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-08 15:44:55

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

事实证明,/fp:fast/arch:AVX2/O1 (或更高的/O1)标志不足以使Visual 2015模式在32位模式下发出FMA指令。您还需要打开带有标志https://msdn.microsoft.com/en-us/library/0zza0de8.aspx/GL

然后Visual 2015将生成一个FMA指令vfmadd213ss

代码语言:javascript
复制
float func1(float x, float y, float z)
{
    return x * y + z;
}

关于std::fma,我打开了一个Microsoft Connect的bug。他们确认了std::fma不编译到FMA指令的行为,因为编译器并不将其视为一个内在的。根据他们的反应,它将在一个未来的更新,以获得最佳的代码可能。

票数 4
EN

Stack Overflow用户

发布于 2016-01-04 19:52:39

MSVC 2015确实为标量运算生成fma指令,但为向量操作生成fma指令(除非明确使用fma内禀)。

我编译了以下代码

代码语言:javascript
复制
//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);
}

使用

代码语言:javascript
复制
cl /c /O2 /arch:AVX2 /fp:fast /FA foo.cpp

在MSVC2015中,它生成了以下程序集

代码语言:javascript
复制
;mul_add
vmovaps xmm3, xmm1
vfmadd213ss xmm3, xmm0, xmm2
vmovaps xmm0, xmm3

代码语言:javascript
复制
;mul_addv
vmovups ymm0, YMMWORD PTR [rcx]
vmulps  ymm1, ymm0, YMMWORD PTR [rdx]
vaddps  ymm0, ymm1, YMMWORD PTR [r8]
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34265982

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档