有没有比计时更好的 C 程序基准测试方法?

发布于 2024-12-05 03:39:21 字数 455 浏览 1 评论 0原文

我正在编写一个小程序,它必须对一个大数组(最多 400 万个文本字符串)进行排序。看起来我在这方面做得很好,因为基数排序和合并排序的组合已经将原始的 q(uick)sort 执行时间减少了一半以下。

执行时间是要点,因为这是我用来对我的代码段进行基准测试的东西。

我的问题是:

是否有比仅仅计时执行时间更好(即更可靠)的程序基准测试方法?它有点工作,但是同一个程序(运行相同的后台进程)如果运行两次,执行时间通常会略有不同。

这有点违背了检测小改进的目的。一些小的改进可以加起来成为一个大的改进...

提前感谢您的任何意见!

结果:

我成功地让 gprof 在 Windows 下工作(使用 gcc 和 MinGW)。与我的普通编译器(tcc)相比,gcc 的表现很差(考虑到执行时间),但它给了我相当多的见解。

I'm coding a little program that has to sort a large array (up to 4 million text strings). Seems like I'm doing quite well at it, since a combination of radixsort and mergesort already cut the original q(uick)sort execution time in less than half.

Execution time being the main point, since this is what I'm using to benchmark my piece of code.

My question is:

Is there a better (i. e. more reliable) way of benchmarking a program than just time the execution? It kinda works, but the same program (with the same background processes running) usually has slightly different execution times if run twice.

This kinda defeats the purpose of detecting small improvements. And several small improvements could add up to a big one...

Thanks in advance for any input!

Results:

I managed to get gprof to work under Windows (using gcc and MinGW). gcc behaves poorly (considering execution time) compared to my normal compiler (tcc), but it gave me quite some insight.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

谈下烟灰 2024-12-12 03:39:21

尝试使用分析工具,它还会显示程序在哪里花费了时间。 gprof 是经典的 C 分析工具,至少在 Unix 上是这样。

Try a profiling tool, that will also show you where the program is spending its time. gprof is the classic C profiling tool, at least on Unix.

瞎闹 2024-12-12 03:39:21

查看 time 命令。它跟踪进程使用的 CPU 时间和挂钟时间。您还可以使用诸如 gprof 之类的工具来分析代码,以查找程序中存在问题的部分。实际上花费了最多的时间。您可以使用代码中的计时器进行技术含量较低的分析。 Boost 有一个很好的timer 类,但很容易推出自己的类。

Look at the time command. It tracks both the CPU time a process uses and the wall-clock time. You can also use something like gprof for profiling your code to find the parts of your program that are actually taking the most time. You could do a lower-tech version of profiling with timers in your code. Boost has a nice timer class, but it's easy to roll your own.

遥远的她 2024-12-12 03:39:21

我认为仅仅测量一段代码的执行时间是不够的。您的环境是一个不断变化的事物,因此您必须采用统计方法来测量执行时间。

本质上,您需要进行 N 次测量,丢弃异常值,并通过不确定性测量来计算平均、中值和标准差运行时间。

这是一个很好的博客,解释了为什么以及如何执行此操作(带有代码): http://blogs.perl.org/users/steffen_mueller/2010/09/your-benchmarks-suck.html

I don't think it's sufficient to just measure how long a piece of code takes to execute. Your environment is a constantly changing thing, so you have to take a statistical approach to measuring execution time.

Essentially you need to take N measurements, discard outliers, and calculate your average, median and standard deviation running time, with an uncertainty measurement.

Here's a good blog explaining why and how to do this (with code): http://blogs.perl.org/users/steffen_mueller/2010/09/your-benchmarks-suck.html

陌路黄昏 2024-12-12 03:39:21

到目前为止,您使用什么来计时执行时间?对于初学者来说,time.h 中有 C89 clock()。在 unixoid 系统上,您可能会找到用于 ITIMER_VIRTUALgetitimer() 来测量进程 CPU 时间。有关详细信息,请参阅相应的手册页。

您还可以使用 POSIX shell 的 times 实用程序来对进程及其子进程使用的处理器时间进行基准测试。分辨率取决于系统,就像任何有关分析的事情一样。尝试将 C 代码包装在一个循环中,根据需要执行多次,以减少基准测试报告时间中的“抖动”。

What do you use for timing execution time so far? There's C89 clock() in time.h for starters. On unixoid systems you might find getitimer() for ITIMER_VIRTUAL to measure process CPU time. See the respective manual pages for details.

You can also use a POSIX shell's times utility to benchmark the processor time used by a process and its children. The resolution is system dependent, like just anything about profiling. Try to wrap your C code in a loop, executing it as many times as necessary to reduce the "jitter" in the time the benchmarking reports.

各自安好 2024-12-12 03:39:21

从测试工具调用您的例程,从而执行 N + 1 次。忽略第一次迭代的时间,然后取迭代 1..N 的平均值。忽略第一次的原因是,由于各种影响,例如虚拟内存、代码分页等,它通常会稍微膨胀。平均 N 次迭代的原因是,您可以消除由其他进程、调度程序引起的伪影。等。

如果您在 Linux 或类似系统上运行,您可能还想使用 taskset 将代码固定到特定的 CPU 核心(假设它是单线程),最好不是核心 0,因为这往往会处理所有中断。

Call your routine from a test harness, whereby it executes N + 1 times. Ignore the timing for the first iteration and then take the average of iterations 1..N. The reason for ignoring the first time is that is is often slightly inflated due to various effects, e.g. virtual memory, code being paged in, etc. The reason for averaging N iterations is that you get rid of artefacts caused by other processes, the scheduler, etc.

If you're running on Linux or similar You might also want to use taskset to pin your code to a specific CPU core (assuming it's single-threaded), ideally not core 0, since this tends to handle all interrupts.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文