我想对C / C ++代码进行基准测试。我想测量cpu时间,挂起时间和周期/字节。我写了一些测量函数但是有周期/字节的问题。
为了获得cpu时间,我使用getrusage()
编写了一个函数RUSAGE_SELF
,我将clock_gettime
与MONOTONIC
一起使用,以获取周期/字节我使用{{ 1}}。
我处理大小的输入缓冲区,例如1024:rdtsc
。我如何基准测试:
char buffer[1024]
1000次: fun2measure(args)
然后,做一个实时计时基准测试,为墙上时间:
`unsigned long i; 双倍时间; double timeTotal = 3.0; //处理3秒
for(timeTaken =(double)0,i = 0; timeTaken< = timeTotal; timeTaken = walltime(1),i ++) fun2measure(参数); `
对于cpu时间(几乎相同):
for(int i=0; i<1000; i++)
fun2measure(args);
但是当我想获得函数的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]
我的问题:
干杯!
第一次编辑:
将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不再是一个问题了:)
答案 0 :(得分:1)
您的cyclecount基准测试存在缺陷,因为它包含walltime / cputime函数调用的成本。但总的来说,我强烈建议你使用合适的探测器,而不是试图重新发明轮子。特别是性能计数器将为您提供您可以信赖的数字。另请注意,循环非常不可靠,因为CPU通常不以固定频率运行,或者内核可能会执行任务切换并暂停您的应用程序一段时间。
我亲自编写基准测试,使得它们运行给定的函数N次,因为N足够大,以便获得足够的样本。在外部,然后我应用一个分析器,如linux perf,以获得一些硬数据来推理。在给定时间内重复基准测试,然后您可以计算stddev / avg值,您可以在运行基准测试的脚本中执行几次并评估探查器的输出。