当前位置:  开发笔记 > 编程语言 > 正文

融合乘法加法和默认舍入模式

如何解决《融合乘法加法和默认舍入模式》经验,为你挑选了1个好方法。

使用GCC 5.3,以下代码符合 -O3 -fma

float mul_add(float a, float b, float c) {
  return a*b + c;
}

生成以下程序集

vfmadd132ss     %xmm1, %xmm2, %xmm0
ret

我注意到GCC -O3已经在GCC 4.8中这样做了.

Clang 3.7带-O3 -mfma产品

vmulss  %xmm1, %xmm0, %xmm0
vaddss  %xmm2, %xmm0, %xmm0
retq

但Clang 3.7与-Ofast -mfmaGCC生成的代码相同-O3 fast.

我很惊讶GCC的确如此,-O3因为从这个答案来看

除非允许使用宽松的浮点模型,否则不允许编译器融合分离的加法和乘法.

这是因为FMA只有一个舍入,而ADD + MUL有两个舍入.因此,编译器将通过融合违反严格的IEEE浮点行为.

但是,从这个链接说

无论FLT_EVAL_METHOD的值如何,任何浮点表达式都可以收缩,即,计算好像所有中间结果都具有无限范围和精度.

所以现在我感到困惑和担忧.

    GCC是否有理由使用FMA -O3

    融合是否违反了严格的IEEE浮点行为?

    如果融合确实违反了IEEE浮点运算,那么GCC的回归__STDC_IEC_559__不是一个矛盾吗?

由于FMA 可以在软件中进行仿真,因此似乎应该有两个用于FMA的编译器开关:一个用于告诉编译器在计算中使用FMA,一个用于告诉编译器硬件具有FMA.


显然,这可以通过选项进行控制-ffp-contract.对于GCC,默认是-ffp-contract=fast和Clang不一样.其他选项例如-ffp-contract=on-ffp-contract=off不生成FMA指令.

例如Clang 3.7 with -O3 -mfma -ffp-contract=fastproduce vfmadd132ss.


我查了一些排列#pragma STDC FP_CONTRACT设置为ON,并OFF-ffp-contract设置为on,offfast.在所有情况下我也使用过-O3 -mfma.

有了GCC,答案很简单.#pragma STDC FP_CONTRACTON或OFF没有区别.只有-ffp-contract事.

GCC它采用fma

    -ffp-contract=fast (默认).

与Clang一起使用 fma

    -ffp-contract=fast.

    with -ffp-contract=on(默认值)和#pragma STDC FP_CONTRACT ON(默认值为OFF).

换句话说,对于Clang,您可以fma使用#pragma STDC FP_CONTRACT ON(因为-ffp-contract=on是默认值)或者使用-ffp-contract=fast.-ffast-math(并因此-Ofast)设定-ffp-contract=fast.


我调查了MSVC和ICC.

使用MSVC,它使用fma指令/O2 /arch:AVX2 /fp:fast.使用MSVC /fp:precise是默认值.

对于ICC,它使用fma -O3 -march=core-avx2(-O1实际上是足够的).这是因为ICC默认使用-fp-model fast.但ICC甚至使用fma -fp-model precise.要禁用与ICC使用FMA -fp-model strict-no-fma.

因此默认情况下,GCC和ICC在启用fma时使用fma(-mfma对于GCC/Clang或-march=core-avx2ICC),但Clang和MSVC不使用.



1> Stephen Cano..:

它不违反IEEE-754,因为IEEE-754在这一点上遵循语言:

语言标准还应定义并要求实现提供允许和禁止对块进行单独或共同的值更改优化的属性.这些优化可能包括但不限于:

...

- 通过乘法和加法合成fusedMultiplyAdd运算.

在标准C中,STDC FP_CONTRACT编译指示提供了控制此值更改优化的方法.因此,GCC默认授权执行融合,只要它允许您通过设置禁用优化STDC FP_CONTRACT OFF.不支持这意味着不遵守C标准.

推荐阅读
围脖上的博博_771
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有