如何计算C ++中的操作?

时间:2008-11-01 08:19:19

标签: c++ performance

如何计算C ++中的操作?我想以更好的方式分析代码而不仅仅是计时代码,因为时间经常被舍入到0毫秒。

11 个答案:

答案 0 :(得分:7)

如果你是计时代码,那么在循环中运行它很多次都是值得的,以避免计时器分辨率的影响。因此,您可以运行10,000次计时并测量运行所有迭代所需的时间。它可能只需要几秒钟就可以运行,您将获得更好的计时数据。

答案 1 :(得分:5)

在考虑性能时,使用“操作次数”是一个坏主意。它没有考虑每个操作的最佳情况/最坏情况周期计数,缓存未命中,管道未命中,潜在(自动)并行化等的差异。

正如格雷格所说,对于微基准测试而言,通常只需运行相同的代码足够长的时间就可以获得合适的时间。

更好的方法是使用实​​际工作负载运行整个应用程序并测量您真正感兴趣的指标,但这是另一回事......

当然有用的是计算代码的复杂性 - 知道方法何时是O(1),O(log n), O(n)等。这通常不涉及了解C ++中各个指令的详细信息 - 尽管需要知道所调用的任何内容的复杂性。 (乔尔关于Shlemiel the Painter and strlen的故事是最明显的例子。)

答案 2 :(得分:4)

示例分析器是一个不错的选择。在Windows上,您可以使用Windows组织中的profiler built into Visual Studioxperf tools。 xperf工具是免费的。以下是我自己的xperf工具的series of postsThis one is about profiling

答案 3 :(得分:3)

生成装配和计数操作。然后查看处理器使用的周期/操作。 然后记住你正在开发一个先发制人的操作系统,但没有一个是有效的。

更严重的是,抬起你的 n 并将你的程序缩放到淫秽大小。这将让您了解您的程序速度。

答案 4 :(得分:3)

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

答案 5 :(得分:3)

您可以通过读取CPU的时间戳计数器( tsc )来进行精确测量,在每个cpu时钟递增1。

不幸的是,读取是在代码中内联一些汇编程序指令完成的。根据底层架构,读取成本在~11(AMD)和~33(Intel) tsc 之间变化。使用1 Ghz CPU,您几乎可以获得纳秒精度。

为了对一段代码执行可靠且无创的测量,您可以:

  • 通过禁用cpu功能来阻止cpu扩展频率,例如 AMD cool'n相当 Intel SpeedStep
  • 重复测试几次,收集数组中的度量值,然后将数据保存到文件中以进行离线分析。
  • 为正在测试的流程选择实时计划政策,例如 SHED_RR SHED_FIFO 。实时策略减少了被测进程与被阻止的其他正常进程/内核线程之间的上下文切换次数。
  • 通过mlockall()系统调用将所有进程的虚拟地址空间锁定在RAM中。

Here你可以找到我为Linux编写的一个准可移植的C ++类,它源自Linux内核,旨在读取架构i386,x86_64和ia64的tsc。

答案 6 :(得分:2)

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

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

答案 7 :(得分:0)

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

答案 8 :(得分:0)

为什么不在分析器下运行代码?这通常会为您提供有关在函数中花费了多少时间以及调用它们的次数的数据。

知道函数被调用了多少次是有用的,因为它可以让你发现潜在的性能问题,如果一个函数被调用的频率远远超过你的预期。

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

答案 9 :(得分:0)

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

答案 10 :(得分:0)

如果您担心程序尽可能快,并且它是单线程的,并且您正在使用IDE,请查看以下内容: How to Optimize Your Program's Performance