基准测试代码 – 我做得对吗?
我想对C / C ++代码进行基准测试。 我想测量cpu时间,挂起时间和周期/字节。 我写了一些测量函数但是有周期/字节的问题。
为了得到一个cpu时间,我用RUSAGE_SELF
编写了一个函数getrusage()
,对于墙上时间我使用带有RUSAGE_SELF
clock_gettime
,得到周期/字节我使用rdtsc
。
我处理一个大小的输入缓冲区,例如1024: char buffer[1024]
。 我如何基准测试:
- 做一个热身阶段,只需调用
fun2measure(args)
1000次:
for(int i=0; i<1000; i++) fun2measure(args);
-
然后,做一个实时基准测试,为墙上时间:
`unsigned long i; 双倍时间; double timeTotal = 3.0; //处理3秒
for(timeTaken =(double)0,i = 0; timeTaken <= timeTotal; timeTaken = walltime(1),i ++)fun2measure(args); `
-
而对于cpu时间(几乎相同):
for (timeTaken=(double)0, i=0; timeTaken <= timeTotal; timeTaken = walltime(1), i++) fun2measure(args);
但是当我想获得函数的cpu循环计数时,我使用这段代码:
`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);
inputsSize
这里inputsSize
是1024,因为它是buffer
的长度。但是当我将totalTime
上升到10s时,我得到奇怪的结果:
10秒:
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]
5s:
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]
4s:
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]
我的问题:
- 那些结果好吗?
- 为什么当我增加时间时,我总是在cpu中获得0个周期/字节?
- 如何衡量此类基准测试的平均时间,平均值,标准差等统计数据?
- 我的基准测试方法100%可以吗?
干杯!
第一次编辑:
将i
改为double
:
Did fun2measure 1138164.00 times in 10.00 seconds for 1024 bytes, 0.410739 cycles/byte [CPU] Did fun2measure 999849.00 times in 10.00 seconds for 1024 bytes, 3.382036 cycles/byte [WALL]
我的结果似乎没问题。 所以问题#2不再是一个问题:)
您的cyclecount基准测试存在缺陷,因为它包含walltime / cputime函数调用的成本。 但总的来说,我强烈建议你使用合适的探测器,而不是试图重新发明轮子。 特别是性能计数器将为您提供您可以信赖的数字。 另请注意,循环非常不可靠,因为CPU通常不以固定频率运行,或者内核可能会执行任务切换并暂停应用程序一段时间。
我个人写基准测试,他们运行一个给定的函数N次,因为N足够大,以便你得到足够的样本。 在外部,然后我应用一个分析器,如linux perf,以获得一些硬数据来推理。 在给定时间内重复基准测试,然后您可以计算stddev / avg值,您可以在运行基准测试的脚本中执行几次并评估分析器的输出。