与天真计算相比,FMA表现

时间:2015-03-23 19:37:04

标签: c++ fma

我试图比较FMA性能(fma()中的math.h)与浮点计算中的朴素乘法和加法。测试很简单。我将为大迭代次数迭代相同的计算。我需要做两件事才能进行精确检查。

  1. 计算时间不应包括其他计算。
  2. 天真乘法和加法不应优化为FMA
  3. 不应优化迭代。即迭代应该按照我的预期进行。
  4. 为了实现上述目标,我做了以下事情:

    1. 函数是内联的,只包含必需的计算。
    2. 使用g ++ -O0选项不优化乘法。 (但是当我查看转储文件时,它似乎为两者生成了几乎相同的代码)
    3. 已使用volatile
    4. 但与天真的乘法和加法相比,结果显示几乎没有差异,甚至更慢fma() 这是我预期的结果(即它们在速度方面没有什么不同)或者我做错了什么?

      规格

      • Ubuntu 14.04.2
      • G ++ 4.8.2
      • Intel(R)Core(TM)i7-4770(3.4GHz,8MB L3缓存)

      我的代码

      #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;
      }
      

1 个答案:

答案 0 :(得分:7)

是的,你做的事情完全错了。至少有两个人。但是,让我们保持简单。

Used g++ -O0 option not to optimize the multiplication

这使您的整个结果完全无关紧要。有趣的事实:在任何一种情况下,函数调用的成本可能都高于计算的成本。

从根本上说,未启用优化的基准测试结果完全没有意义。你不能把它们关掉,希望最好。他们绝对必须启用。

其次,FMA与常规乘法和加法是一个复杂的情况 - 有一些事情,如延迟与吞吐量以及其他可以成倍增加的问题。

简而言之,您的基准测试根本不是基准,它只是一堆产生无意义垃圾的随机指令。

如果您需要准确的基准测试,则必须完全准确地重现实际使用情况。包括周围的代码,编译器优化,整个shebang。