基准测试代码 - 我做得对吗?

时间:2013-07-25 14:13:13

标签: c++ c performance benchmarking microbenchmark

我想对C / C ++代码进行基准测试。我想测量cpu时间,挂起时间和周期/字节。我写了一些测量函数但是有周期/字节的问题。

为了获得cpu时间,我使用getrusage()编写了一个函数RUSAGE_SELF,我将clock_gettimeMONOTONIC一起使用,以获取周期/字节我使用{{ 1}}。

我处理大小的输入缓冲区,例如1024:rdtsc。我如何基准测试:

  1. 做一个预热阶段,只需拨打char buffer[1024] 1000次:
  2. fun2measure(args)

    1. 然后,做一个实时计时基准测试,为墙上时间:

      `unsigned long i; 双倍时间; double timeTotal = 3.0; //处理3秒

      for(timeTaken =(double)0,i = 0; timeTaken< = timeTotal; timeTaken = walltime(1),i ++)     fun2measure(参数); `

    2. 对于cpu时间(几乎相同):

      for(int i=0; i<1000; i++) fun2measure(args);

    3. 但是当我想获得函数的cpu循环计数时,我使用这段代码:

      for (timeTaken=(double)0, i=0; timeTaken <= timeTotal; timeTaken = walltime(1), i++)
               fun2measure(args);

      然后,计算周期/字节:`unsigned long s = cyclecount(); for (timeTaken=(double)0, i=0; timeTaken <= timeTotal; timeTaken = walltime(1), i++) { fun2measure(args); } unsigned long e = cyclecount(); unsigned long s = cyclecount(); for (timeTaken=(double)0, i=0; timeTaken <= timeTotal; timeTaken = cputime(1), i++) { fun2measure(args); } unsigned long e = cyclecount();` 。此处((e - s) / (i * inputsSize);为1024,因为它是inputsSize的长度。但当我将buffer提升到10s时,我会发现奇怪的结果:

      10s:

      totalTime

      表示5s:

      Did fun2measure 1148531 times in 10.00 seconds for 1024 bytes, 0 cycles/byte [CPU]
      Did fun2measure 1000221 times in 10.00 seconds for 1024 bytes, 3.000000 cycles/byte [WALL]
      

      for 4s:

      Did fun2measure 578476 times in 5.00 seconds for 1024 bytes, 0 cycles/byte [CPU]
      Did fun2measure 499542 times in 5.00 seconds for 1024 bytes, 7.000000 cycles/byte [WALL]
      

      我的问题:

      1. 这些结果好吗?
      2. 为什么当我增加时间时,我总是在cpu中得到0个周期/字节?
      3. 如何衡量此类基准测试的平均时间,平均值,标准差等统计数据?
      4. 我的基准测试方法是100%好吗?
      5. 干杯!

        第一次编辑:

        Did fun2measure 456828 times in 4.00 seconds for 1024 bytes, 4 cycles/byte [CPU] Did fun2measure 396612 times in 4.00 seconds for 1024 bytes, 3.000000 cycles/byte [WALL] 更改为i后:

        double

        我的结果似乎没问题。所以问题#2不再是一个问题了:)

1 个答案:

答案 0 :(得分:1)

您的cyclecount基准测试存在缺陷,因为它包含walltime / cputime函数调用的成本。但总的来说,我强烈建议你使用合适的探测器,而不是试图重新发明轮子。特别是性能计数器将为您提供您可以信赖的数字。另请注意,循环非常不可靠,因为CPU通常不以固定频率运行,或者内核可能会执行任务切换并暂停您的应用程序一段时间。

我亲自编写基准测试,使得它们运行给定的函数N次,因为N足够大,以便获得足够的样本。在外部,然后我应用一个分析器,如linux perf,以获得一些硬数据来推理。在给定时间内重复基准测试,然后您可以计算stddev / avg值,您可以在运行基准测试的脚本中执行几次并评估探查器的输出。