【问题标题】:Timing operator+, operator-, operator*, and operator/定时 operator+、operator-、operator* 和 operator/
【发布时间】:2013-06-21 23:52:03
【问题描述】:

我有一个简单的数学向量类,其中运算符重载。我想为我的操作员获得一些计时结果。我可以通过对以下代码进行计时来轻松地计时我的 +=、-=、*= 和 /=:

Vector sum;
for(size_t i = 0; i<iter; ++i)
  sum += RandVector();
cout << sum << endl;

然后我可以减去生成迭代随机向量所需的时间。在我的测试中,Vector 是 3 维的,iter = 10,000,000。

我尝试用 +,-,*,/ 做类似的事情:

Vector sum;
for(size_t i = 0; i<iter; ++i)
  sum = sum + RandVector();
cout << sum << endl;

然后减去生成迭代随机向量和执行迭代分配所需的时间,但这给出了一个“负”时间,让我相信编译器正在以某种方式优化操作,或者发生了一些奇怪的事情。

我在 Fedora Linux 机器上使用 gcc-4.7.2 和 -O3。

这是我的计时码:

clock_t start, k = clock();
do start = clock();
while(start == k);

F()();

clock_t end = clock();

double time = double(end-start)/double(CLOCKS_PER_SEC);
cout << time - time_iter_rand_v - time_iter_ass;

这里的 F 是执行上述代码的函数对象。 time_iter_rand_v 是创建迭代随机向量所需的时间,time_iter_ass 是迭代分配操作所需的时间。

然后我的问题是如何仅获得 operator+ 函数的准确计时而不是任何分配或随机向量生成?

【问题讨论】:

  • 你的计时怎么样?
  • 我正在使用 的时钟()
  • 编译器不能让时钟倒转,可以吗?很明显你的计时码是错误的。
  • 我建议将您的计时码添加到问题中。这可能是错误的一点。
  • 优化的问题(Adrian 回答)似乎很中肯:stackoverflow.com/q/6130100/1715716

标签: c++ performance benchmarking


【解决方案1】:

当优化开启时,你真的无法获得准确的时间。原因在于编译器具有移动代码的能力。

如果将时间存储变量设置为 volatile,则它们相对于彼此的位置不会因为移动而受到优化。但是,它们周围的代码是,除非它们正在分配或调用带有 volatile 变量的函数(这包括使 *this volatile 的 volatile 成员函数)。

如果您期望线性执行,优化可以对代码做很多奇怪的事情。

【讨论】:

    【解决方案2】:

    只需创建一个RandVector()s 的向量并遍历它们。它将解决测量生成时间的问题。 至于赋值,我认为它归结为编译器如何优化它。

    【讨论】:

      【解决方案3】:

      一种基本的基准测试方法是使用gettimeofday:

      #include <stdio.h>
      #include <stdlib.h>
      #include <sys/time.h>
      #include <sys/types.h>
      
      #include <cstring>
      
      
      
      //-------------------  Handle time in milliseconds  ----------------------//
      
      /*
       * Return 1 if the difference is negative, otherwise 0.
       */
      int timeval_subtract(struct timeval *result, struct timeval *t2, struct timeval *t1)
      {
          long int diff = (t2->tv_usec + 1000000 * t2->tv_sec) - (t1->tv_usec + 1000000 * t1->tv_sec);
          result->tv_sec = diff / 1000000;
          result->tv_usec = diff % 1000000;
      
          return (diff<0);
      }
      
      void timeval_print(struct timeval *tv)
      {
          char buffer[30];
          time_t curtime;
      
          printf("%ld.%06ld", tv->tv_sec, tv->tv_usec);
          curtime = tv->tv_sec;
          strftime(buffer, 30, "%m-%d-%Y  %T", localtime(&curtime));
          printf(" = %s.%06ld\n", buffer, tv->tv_usec);
      }
      
      // usage :
      /*
      
          struct timeval tvBegin, tvEnd, tvDiff;
      
          // begin
          gettimeofday(&tvBegin, NULL);
      
          // lengthy operation
          int i,j;
          for(i=0;i<999999L;++i) {
              j=sqrt(i);
          }
      
          //end
          gettimeofday(&tvEnd, NULL);
      
          // diff
          timeval_subtract(&tvDiff, &tvEnd, &tvBegin);
          printf("%ld.%06ld\n", tvDiff.tv_sec, tvDiff.tv_usec);
      
      
       */
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-12
        • 2020-04-13
        相关资源
        最近更新 更多