基准代码——我做得对吗



我想对C/C++代码进行基准测试。我想测量cpu时间、墙时间和周期/字节。我写了一些度量函数,但循环/字节有问题。

为了获得cpu时间,我用RUSAGE_SELF编写了一个函数getrusage(),对于墙时间,我使用clock_gettimeMONOTONIC,为了获得周期/字节,我使用了rdtsc

我处理大小为1024:char buffer[1024]的输入缓冲区。如何进行基准测试:

  1. 进行热身阶段,只需拨打fun2measure(args) 1000次:

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

  1. 然后,为墙时间做一个真正的计时基准:

    `无符号长i;双倍计时;double timeTotal=3.0;//处理3秒

    对于(timeTake=(双)0,i=0;时间占用<=timeTotal;timeTake=walltime(1),i++)fun2measure(args);`

  2. 对于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);。这里CCD_ 11是1024,因为它是CCD_。但当我把totalTime提高到10时,我会得到奇怪的结果:

10s:

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]

5秒:

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]

我的问题:

  1. 这些结果可以吗
  2. 为什么当我增加时间时,我总是在cpu中获得0个周期/字节
  3. 如何测量此类基准的平均时间、平均值、标准差等统计数据
  4. 我的基准测试方法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足够大,这样你就可以获得足够的样本。在外部,我应用了一个探查器,比如linuxperf,来给我一些难以推理的数字。在给定的时间内重复基准测试,然后可以计算stddev/avg值,这可以在运行基准测试几次并评估探查器输出的脚本中完成。

相关内容

  • 没有找到相关文章

最新更新