C 中的性能/分析测量

Posted

技术标签:

【中文标题】C 中的性能/分析测量【英文标题】:Performance/profiling measurement in C 【发布时间】:2010-01-13 09:43:23 【问题描述】:

我正在用 C 做一些原型设计工作,我想比较一个程序需要多长时间才能完成各种小修改。

我一直在使用clock;来自 K&R:

clock 返回程序自执行开始以来使用的处理器时间,如果不可用,则返回-1

这对我来说似乎是明智的,并且给出的结果与我的期望大致相符。但是有没有更好的方法可以用来查看哪些修改会提高/降低我的代码效率?

更新:我对 Windows 和 Linux 都感兴趣;对两者都适用的东西是理想的。

更新 2:我对分析一个复杂问题的兴趣不如一个简单程序从开始到结束的总运行时间/时钟周期——我已经知道我的程序的哪些部分很慢. clock 似乎符合这个要求,但我不知道它对后台运行的其他进程和占用处理器时间的攻击有多么脆弱。

【问题讨论】:

我不知道有一个分析器可以在多个操作系统上工作。要么使用多个(针对每个 O/S),要么针对一个 O/S 使用一个,并希望您在一个平台上进行剖析而做出的改进也将自动在另一个平台上得到改进。 【参考方案1】:

忘记 time() 函数,你需要的是:

Valgrind!

KCachegrind 是检查 callgrind 分析统计数据的最佳 GUI。过去我将应用程序移植到 linux just,以便我可以使用这些工具进行分析。

【讨论】:

【参考方案2】:

对于总体运行时间的粗略测量,有time ./myprog

但对于性能测量,您应该使用分析器。对于 GCC,有 gprof

这都是假设一个 Unix-ish 环境。我确信有类似的 Windows 工具,但我不熟悉它们。

编辑:澄清:我建议反对在您的代码中使用任何 gettime() 样式函数。 Profiler 已经开发了数十年,可以用 5 行代码完成您尝试完成的工作,并提供了一种更强大、更通用、更有价值且更简单的方法来找出您的代码在哪里花费了它的周期。

【讨论】:

【参考方案3】:

我发现计时程序和寻找优化的东西是两个不同的问题,对于这两个问题,我个人更喜欢低技术。

对于计时,诀窍是通过在其周围缠绕一个循环来使其花费足够长的时间。例如,如果您将一个操作迭代 1000 次并使用秒表计时,那么当您移除循环时,秒会变为毫秒。

为了找到要优化的东西,有一些代码片段(终端指令和函数调用)负责不同的时间部分。在此期间,它们暴露在堆栈上。因此,您可以在程序周围环绕一个循环以使其花费足够长的时间,然后使用stackshots。要优化的代码会跳出来。

【讨论】:

+1 用于循环以延长持续时间,我希望我可以为最后一段添加另一个 +1。 @ChrisW:生物学家称之为“放大信号”,当他们复制数百万个 DNA 副本以便读取它时。【参考方案4】:

在 POSIX 中(例如在 Linux 上),您可以使用 @987654321@ 获得更高精度的计时值(微秒)。

在 Win32 中,@987654322@ 很受欢迎。

注意 CPU 时钟变化的影响,如果您的 CPU 在测试期间决定降低时钟,结果可能会出现偏差。

【讨论】:

【参考方案5】:

如果您可以使用 POSIX 函数,请查看clock_gettime。我从谷歌快速搜索中找到了an example,了解如何使用它。要测量程序占用的处理器时间,如果您的系统支持,您需要将CLOCK_PROCESS_CPUTIME_ID 作为第一个参数传递给clock_gettime。由于clock_gettime 使用struct timespec,您可能可以获得有用的纳秒级分辨率。

正如其他人所说,对于任何严肃的分析工作,您都需要使用专用的分析器。

【讨论】:

以上是关于C 中的性能/分析测量的主要内容,如果未能解决你的问题,请参考以下文章

python性能测量工具cProfile

Web 性能测量中的“交互时间”指标

获取 C 中的进程性能计数器

警告消息:使用 rpart 的插入符号 train() 中的“重采样性能测量中的缺失值”

如何测量多线程应用程序中的缓存性能?

如何衡量 Java 开发中的性能