0

我写了一些函数来对一个函数/一段代码进行基准测试。我这样做:

start = timer
for(1 second)
   call fun
   iterations++
stop = timer

然后我有一个平均(平均)时间:(停止-开始/迭代),对吧?

单次调用太“短”而无法测量,那么我如何从这种类型的测量、标准差、四分位数等中计算出来……?

4

4 回答 4

4

标准差和四分位数都处理组中值的分布。

只需一次测量,这些就变得微不足道或毫无意义。由于只有一个测量值,该值是平均值、最小值、最大值和众数。由于没有任何测量值偏离平均值,因此方差和标准偏差为零。

于 2013-08-29T15:10:28.033 回答
1

您必须找到一种足够精确地测量时间的方法。您需要单独调用的时间fun才能获得任何有意义的标准偏差等。

这个问题可能包含有用的提示,我敢肯定那里也有很多特定于平台的高分辨率计时器。

于 2013-08-29T15:13:12.977 回答
1

如果单个呼叫太短而无法测量,那么您为什么要关心它需要多长时间?

我有点开玩笑,但是如果您使用的是 Intel Linux,并且您的进程被固定到一个内核,您可以读取 CPU 的时间戳计数器 (TSC),这是您可以获得的最高分辨率刻度。在最近的英特尔 CPU 中,它在标称 CPU 频率上非常稳定地运行,与实际频率无关(变化很大)。如果您在 Google 上搜索“rdtsc”,您会发现几个您可以调用的 rdtsc() 函数的实现。然后,您可以尝试以下操作:

uint64_t tic, elapsed[10000];

for(i=0; i<10000; i++) {
    tic = rdtsc()
    my_func()
    elapsed[i] = tic - rdtsc()
}

这可能会让您在单个函数调用的可能有点/有点半有效的值的范围内,然后您可以从中生成您想要的任何统计数据(均值/众数/中值/方差/std.dev。)。这样做的有效性值得商榷,但它是最好的,可以用你的方法来完成。我更倾向于在下面运行整个应用程序perf record,然后使用它perf report来查看周期在哪里消耗并专注于它。

于 2013-08-29T22:17:04.670 回答
1

一般来说,由于处理速度和获得微和毫秒分辨率的麻烦,大多数性能测量都是基于大量迭代。

例如:

  1. 读取开始时间
  2. 1,000,000 次迭代
  3. 执行功能
  4. 结束
  5. 阅读结束时间。

持续时间是结束时间 - 开始时间。平均执行时间是持续时间除以迭代次数。

使用平均时间还有其他原因:操作系统中断、数据缓存未命中以及可能的外部因素(例如硬盘访问)。

要进行更精确的测量,您将不得不使用“测试点”和示波器。在迭代之前将高脉冲写入测试点,然后再写入低脉冲。设置示波器以捕获持续时间。如果您的示波器具有统计功能和存储功能,请将测试点写入移动到功能执行之前和之后。

于 2013-08-29T20:04:06.413 回答