测量所选循环的执行时间

时间:2010-04-29 18:43:08

标签: performance gprof gettimeofday vtune oprofile

我想测量C程序中所选循环的运行时间,以便查看在这些循环中花费了执行程序(在linux上)的总时间的百分比。我应该能够指定应该测量性能的循环。我在过去几天尝试了几种工具(vtune,hpctoolkit,oprofile),但似乎没有人这样做。他们都找到了性能瓶颈,只是为那些人展示了时间。那是因为这些工具只存储超过阈值(~1ms)的时间。因此,如果一个循环花费的时间少于那个循环,则不会报告其执行时间。

gprof的基本块计数功能取决于现在不支持的旧编译器中的功能。

我可以使用gettimeofday或类似的东西手动编写一个简单的计时器,但在某些情况下,它不会给出准确的结果。例如:

for (i = 0; i < 1000; ++i)
{
    for (j  = 0; j < N; ++j)
    {
        //do some work here
    }
}

现在我想测量在内循环中花费的总时间,我将不得不在第一个循环中调用gettimeofday。因此,gettimeofday本身将被调用1000次,这会引入自己的开销,结果将是不准确的。

3 个答案:

答案 0 :(得分:2)

除非你的CPU周围有电路仿真器或分线盒,否则没有定时单循环或单指令的时间。您需要将测试运行批量增加到每个至少需要几秒钟的时间,以减少由于CPU,操作系统等中发生的其他事情而导致的错误。

如果您想要确切地知道特定循环执行所需的时间,并且执行时花费的时间少于1秒,那么您将需要人为地增加迭代次数得到一个高于“本底噪声”的数字。然后,您可以将该数字除以人为膨胀的迭代次数,得到一个数字,表示一次通过目标循环所需的时间。

如果您想比较不同循环样式或技术的性能,同样的事情就是:您需要增加迭代次数或通过测试代码才能获得测量结果你感兴趣的是你所测量的时间片。

无论您是使用CPU提供的亚毫秒级高性能计数器,系统日期时间时钟还是挂钟来衡量测试所用的时间,都可以测量性能。

否则,你只是测量白噪声。

答案 1 :(得分:0)

通常,如果要测量内循环所花费的时间,则将时间get例程放在外部循环之外,然后除以(外部)循环计数。如果你期望内部循环的时间对于任何j都是相对恒定的,那就是。

任何分析指令都会产生自己的开销,但可能无论在何处插入,开销都是相同的,因此“它们都会在洗涤中出现”。大概你正在寻找两个比较过程的运行时间之间存在相当大差异的地方,这样的一对函数调用不会成为一个问题(因为你也需要一个在“结束”,以获得时间) delta)因为一个例程比另一个例程贵2倍或更多。

大多数平台也提供某种更高分辨率的计时器,尽管我们在这里使用的计时器隐藏在API后面,因此“客户端”代码是跨平台的。我肯定有点看,你可以把它打开。虽然在这里,你的准确度几乎不会超过1ms,所以最好连续几次运行代码并整个运行时间(然后除以循环计数,natch)。

答案 2 :(得分:0)

我很高兴你在寻找百分比,因为这很容易获得。只是让它运行。如果它快速运行,在它周围放一个外环,这样需要很长时间。这不会影响百分比。在它运行时,获取stackshots。您可以使用 gdb 中的Ctrl-Break执行此操作,也可以使用 pstack lsstack 。只需看看有多少百分比的叠加显示你关心的代码。

假设循环需要一些时间,如0.2(20%),你需要N = 20个样本。那么应该显示它们的样本数量平均为20 * 0.2 = 4,样本数量的标准差将是sqrt(20 * 0.2 * 0.8)= sqrt(3.2)= 1.8,所以如果你想要更高的精度,拿更多的样品。 (我个人认为精确度被高估了。)