我正在尝试比较FMA性能(fma()在math.h中)与朴素乘法和加法在浮点计算中。测试很简单。对于较大的迭代次数,我将迭代相同的计算。为了进行精确的检查,我必须做到两件事。
为了达到上述目的,我做了以下工作:
-O0选项不优化乘法。(但当我查看转储文件时,它似乎为这两个文件生成了几乎相同的代码)volatile。但结果表明,与朴素乘法和加法相比,fma()几乎没有差别,甚至更慢。,这是我想要的结果(即它们在速度上并没有真正的不同),还是我做错了什么?
Spec
我的代码
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <chrono>
using namespace std;
using namespace chrono;
inline double rand_gen() {
return static_cast<double>(rand()) / RAND_MAX;
}
volatile double a, b, c;
inline void pure_fma_func() {
fma(a, b, c);
}
inline void non_fma_func() {
a * b + c;
}
int main() {
int n = 100000000;
a = rand_gen();
b = rand_gen();
c = rand_gen();
auto t1 = system_clock::now();
for (int i = 0; i < n; i++) {
non_fma_func();
}
auto t2 = system_clock::now();
for (int i = 0; i < n; i++) {
pure_fma_func();
}
auto t3 = system_clock::now();
cout << "non fma" << endl;
cout << duration_cast<microseconds>(t2 - t1).count() / 1000.0 << "ms" << endl;
cout << "fma" << endl;
cout << duration_cast<microseconds>(t3 - t2).count() / 1000.0 << "ms" << endl;
}发布于 2015-03-23 19:44:44
是的,你做了完全错误的事情。至少有两件事。但让我们保持简单。
Used g++ -O0 option not to optimize the multiplication这使得您的整个结果完全无关紧要。有趣的事实:在这两种情况下,函数调用的成本可能都高于计算的成本。
从根本上说,不启用优化的基准测试的结果是完全没有意义的。你不能就这样把他们关了然后抱着最好的希望。他们绝对必须被启用。
其次,FMA和常规的乘加是一种复杂的情况--比如延迟和吞吐量,以及其他的事情,乘法和加可以成为赢家。
简而言之,你的基准根本不是一个基准,它只是一堆随机指令,产生毫无意义的垃圾。
如果你想要一个准确的基准,你必须准确地再现实际使用情况--完全。包括周围的代码,编译器的优化,整个系统。
https://stackoverflow.com/questions/29218884
复制相似问题