假设在某些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 )
答案 0 :(得分:7)
最近,在Build 2014中,Eric Brumer就这一主题发表了非常好的演讲(see here)。 谈话的底线是
使用融合乘法累积(又名FMA)会影响性能。
在Intel CPU中,FMA指令需要5个周期。相反,进行乘法(5个循环)和加法(3个循环)需要8个循环。使用FMA,您将获得两项奖励(见下图)。
但是,FMA似乎不是指令的圣洁。如下图所示,FMA可以在某些引用中损害性能。
以同样的方式,您的案例fma(triplet1) + fma(triplet2) + fma(triplet 3)
需要21个周期,而如果您要使用FMA执行相同的操作则需要30个周期。这表现了30%的性能提升。
在代码中使用FMA需要使用compiler intrinsics。尽管如此,除非你是C ++编译器程序员,否则FMA等并不是你应该担心的事情。如果不是,请让编译器优化处理这些技术问题。一般来说,在这种关注下,所有邪恶的根源(即,过早的优化)都要解释其中一个伟大的(即Donald Knuth)。