我遇到这个页面,发现有一个奇怪的浮动乘法加法 函数 - fma和fmaf.它说结果是这样的:
(x * y) + z #fma(x,y,z)
Run Code Online (Sandbox Code Playgroud)
并且值是无限精度并且对结果格式进行一次舍入.
然而,AFAICT我以前从未见过这样的三元手术.所以我想知道这个功能的cumstom用法是什么.
如何使用AVX和FMA指令禁用自动矢量化?我仍然希望编译器自动使用SSE和SSE2,而不是FMA和AVX.
我的代码使用AVX检查其可用性,但GCC在自动矢量化时不会这样做.因此,如果我-mfma在Haswell之前编译并在任何CPU上运行代码,我会得到SIGILL.如何解决这个问题?
我有一些用numpy编写的代码,我正在考虑将它移植到Fortran以获得更好的性能.
我做过几次的一个操作就是将两个数组的元素乘积相加:
sum(A*B)
Run Code Online (Sandbox Code Playgroud)
看起来融合的乘法 - 加法指令会对此有所帮助.我当前的处理器不支持这些说明,所以我还无法测试.但是,我可能会升级到支持FMA3(Intel Haswell处理器)的新处理器.
有没有人知道用"-march = native"(或ifort等价物)编译程序是否足以让编译器(gfortran或ifort)明智地使用SIMD指令来优化代码,或者你认为我会必须要编译器或代码?
根据文档,有一个fma()功能math.h.这非常好,我知道FMA如何工作以及如何使用它.但是,我不太确定这在实践中如何实施?我最感兴趣的是x86和x86_64架构.
是否存在FMA的浮点(非向量)指令,可能是IEEE-754 2008定义的?
是使用FMA3还是FMA4指令?
在依赖精度的情况下,是否存在确保使用真实FMA的内在因素?
这个问题适用于Haswell上带有XMM/YMM寄存器的压缩单预备浮点运算.
因此,根据Agner Fog 提供的令人敬畏的,令人敬畏的 表,我知道MUL可以在端口p0和p1上完成(recp thruput为0.5),而只有ADD只在端口p1上完成(recp thruput为1) ).我可以除了这个限制,但我也知道FMA可以在端口p0或p1上完成(recp吞吐量为0.5).因此,当我的FMA可以使用p0或p1并同时执行ADD和MUL时,为什么普通ADD仅限于p1是令人困惑的.我误解了桌子吗?或者有人可以解释为什么会这样?
也就是说,如果我的读数是正确的,为什么英特尔不会仅使用FMA op作为普通MUL和普通ADD的基础,从而增加ADD和MUL的吞吐量.或者,什么会阻止我使用两个同时独立的FMA操作来模拟两个同时独立的ADD操作?做ADD-by-FMA有哪些处罚?显然,使用的寄存器数量更多(ADD为2 reg,而FMA为ADD为3 reg),但除此之外?
如果C#编译器/抖动在所使用的硬件上可用,是否使用融合的乘法加法运算?如果可以,我是否需要设置任何特定的编译器设置才能利用它?
我的意图是将补偿算法用于扩展精度算术,并且其中一些可以编写为使用FMA。
我对-ffp-contractGNU GCC中的标志有疑问(请参阅https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html)。
标志文档编写如下:
-ffp-contract=off禁用浮点表达式收缩。-ffp-contract=fast如果目标对它们有本机支持,则启用浮点表达式收缩,例如形成融合的乘法加法运算。-ffp-contract=on如果语言标准允许,则启用浮点表达式收缩。目前尚未实现,并且将其视为-ffp-contract=off。默认值为-ffp-contract=fast。
现在的问题是:
来自Nvidia发行说明:
The nvcc compiler switch, --fmad (short name: -fmad), to control the contraction of
floating-point multiplies and add/subtracts into floating-point multiply-add
operations (FMAD, FFMA, or DFMA) has been added:
--fmad=true and --fmad=false enables and disables the contraction respectively.
This switch is supported only when the --gpu-architecture option is set with
compute_20, sm_20, or higher. For other architecture classes, the contraction is
always enabled.
The --use_fast_math option implies --fmad=true, and enables the contraction.
Run Code Online (Sandbox Code Playgroud)
我有两个内核 - 一个是纯粹的计算绑定,有很多乘法,而另一个是内存绑定.当我这样做时,我注意到我的计算密集型内核的性能持续改善(大约5%),-fmad=false并且当我为内存绑定内核关闭时,性能下降相同.所以,FMA对我的内存绑定内核工作得更好,但我的计算绑定内核可以通过关闭它来挤出一点性能.可能是什么原因?我的设备是M2090,我使用的是CUDA 4.2.
完整的编译选项:(
-arch,sm_20,-ftz=true,-prec-div=false,-prec-sqrt=false,-use_fast_math,-fmad=false …
假设在一些C或C++代码中,我有一个名为的函数T fma( T a, T b, T c ),它执行1次乘法和1次加法,就像这样( a * b ) + c; 我该如何优化多个mul并添加步骤?
例如,我的算法需要用链接和求和的3或4个fma操作来实现,我怎么能写这个是一种有效的方式,在语法或语义的哪个部分我应该特别注意?
我还想了解关键部分的一些提示:避免更改CPU的舍入模式以避免刷新cpu管道.但是我很确定只是+在多次调用之间使用操作fma不应该改变它,我说"非常肯定",因为我没有太多的CPU来测试它,我只是遵循一些逻辑步骤.
我的算法类似于多个fma调用的总和
fma ( triplet 1 ) + fma ( triplet 2 ) + fma ( triplet 3 )
Run Code Online (Sandbox Code Playgroud) 使用Haswell的FMA指令考虑以下指令序列:
__m256 r1 = _mm256_xor_ps (r1, r1);
r1 = _mm256_fmadd_ps (rp1, m6, r1);
r1 = _mm256_fmadd_ps (rp2, m7, r1);
r1 = _mm256_fmadd_ps (rp3, m8, r1);
__m256 r2 = _mm256_xor_ps (r2, r2);
r2 = _mm256_fmadd_ps (rp1, m3, r2);
r2 = _mm256_fmadd_ps (rp2, m4, r2);
r2 = _mm256_fmadd_ps (rp3, m5, r2);
__m256 r3 = _mm256_xor_ps (r3, r3);
r3 = _mm256_fmadd_ps (rp1, m0, r3);
r3 = _mm256_fmadd_ps (rp2, m1, r3);
r3 = _mm256_fmadd_ps (rp3, m2, r3);
Run Code Online (Sandbox Code Playgroud)
可以使用非FMA指令表达相同的计算,如下所示:
__m256 i1 = _mm256_mul_ps (rp1, m6); …Run Code Online (Sandbox Code Playgroud)