2008-11-01 78 views
5

如何计算C++中的操作?我希望以更好的方式分析代码,而不仅仅是计时,因为时间通常取整为0毫秒。如何计算C++中的操作?

+0

指定你是什么“的意思计数操作“。有些工具可以像分析器一样分析代码中的函数调用,但是您也可以看到,添加相应的开关和生成的汇编代码。 – 2008-11-01 08:54:20

回答

3

可以通过读取CPU,它是由一个在每个CPU时钟递增的时间戳计数器(TSC)做精确的测量。

不幸的是,读取操作会在代码中内嵌一些汇编指令。取决于底层架构,读取成本在〜11(AMD)和〜33(Intel)tsc之间变化。使用1 Ghz CPU,您几乎可以达到纳秒级精度。

为了执行的代码可以一个部分的可靠和非侵入性的测量:通过禁用的CPU功能如AMD cool'n

  • 防止CPU缩放频率相当或英特尔SpeedStep
  • 多次重复测试,收集数组中的度量值,然后将数据保存到文件以进行离线分析。
  • 为被测试过程选择实时调度策略,如SHED_RRSHED_FIFO。实时策略减少被测试进程和其他正常进程/内核线程之间的上下文切换次数,这些进程被阻止。
  • 通过mlockall()系统调用来锁定RAM中所有进程的虚拟地址空间。

Here你可以找到一个准便携的C++类,我写的Linux,从Linux内核导出,旨在读取TSC的架构是i386,x86_64的和IA64。

7

如果你是计时代码,它是值得在循环中运行很多次,以避免计时器分辨率的影响。所以你可以运行你计时10,000次的东西,并测量运行所有迭代所花费的时间。它可能只需要几秒钟的运行,你会得到更好的时间数据。

+1

唯一的困难就是基准会彻底加热'缓存',而代码通常在冷藏缓存上运行。但是测量低温缓存性能很困难。 – 2008-11-01 16:21:41

+0

是的,除非您正在测量缓存本身的性能,否则您需要禁用缓存以进行正确的性能测试。 – 2008-11-02 01:02:01

5

在考虑性能时,使用“操作次数”是一个坏主意。它没有考虑到每个操作的最佳/最差情况循环计数,缓存缺失,流水线丢失,潜在(自动)并行化等的成本之间的差异。

正如Greg所说,通常它是更好的一个微基准标记的想法就是运行相同的代码足够多的时间来获得相当的时间。

更妙的是与实际工作量运行你的整个应用程序和衡量你真正感兴趣的指标,但是这是一个不同的问题...

什么当然是有用的是制定出你的代码的复杂度为复杂度为 - 知道何时方法将是O(1),O(log n),O(n)等。这通常不涉及知道C++中单个指令的细节 - 虽然你需要知道任何你调用的复杂性。 (Joel的故事Shlemiel the Painter and strlen就是最明显的例子。)

0

使用更高分辨率的定时器。

3

生成程序集和计数操作。然后查看处理器使用的周期/操作。 然后记得你正在开发一个先发制人的操作系统,并且没有一个是有效的。

更严重的是,抬起你的n并将你的程序缩放到淫秽尺寸。这会让你知道你的程序速度是多少。

2

如果您希望实际操作数量来自您的硬件,那么您可能需要考虑安装像PAPI这样的软件包 - 性能API--它可以在许多不同的操作系统和处理器组合中使用。它使用实际的硬件计数器并报告直接或派生值,以获得许多不同的性能指标,例如Total Ops,FLOPS,缓存命中/未命中等等。它还可以访问更高分辨率的定时器。

这不是最简单的软件包,但报告级别确实可以帮助您分析应用程序在硬件上的行为。

3

在Linux上使用valgrind。它具有指令级时序,包括缓存分析。

0

为什么不只是在探查器下运行你的代码?这通常会为您提供关于在函数中花费多少时间以及调用多少次的数据。

知道函数被调用的次数是有用的,因为如果函数被调用的次数远远超过您的感觉,它可以让您发现潜在的性能问题。

当然,使用探查器会使代码变慢,但在添加任何类型的仪器时这是不可避免的。

0

如果你想在不使用分析器的情况下精确计时(在windows上),你可以看看this thread,它提供了不同的分析C++代码的方法。