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]
原文地址:https://www.jb51.cc/c/118947.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。