如何将多个fma操作链接在一起以获得性能?

假设在某些C或C ++代码中,我有一个名为T fma( T a, T b, T 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 ) 

最近,在Build 2014中,Eric Brumer就这个话题发表了非常好的演讲( 见这里 )。 谈话的底线是

使用Fused Multiply Accumulate(aka FMA)无处不在会损害性能。

在Intel CPU中,FMA指令需要5个周期。 而是进行乘法(5个循环)和加法(3个循环)需要8个循环。 使用FMA,您将获得两项奖励(见下图)。

在此处输入图像描述

然而,FMA似乎不是指令的冬青。 正如您在下面的图片中看到的那样,FMA可以在某些引用中损害性能。

在此处输入图像描述

以同样的方式,你的案例fma(triplet1) + fma(triplet2) + fma(triplet 3)花费21个周期,而如果你用FMA做同样的操作将花费30个周期。 这是性能提升30%。

在代码中使用FMA需要使用编译器内在函数 。 尽管如此,除非你是C ++编译器程序员,否则FMA等并不是你应该担心的事情。 如果不是,请让编译器优化处理这些技术问题。 一般来说,在这种担忧之下,所有邪恶的根源(即过早优化)都要解释其中一个伟大的(即Donald Knuth)。