如何准确测量性能,排除后台程序干扰?

Posted

技术标签:

【中文标题】如何准确测量性能,排除后台程序干扰?【英文标题】:How to measure performance accurately, excluding background program interference? 【发布时间】:2016-10-12 21:33:20 【问题描述】:

我会在 Linux 桌面上测量程序执行时间,例如计算斐波那契数。测量方法可以是在代码中使用 time 命令或 clock() 函数等。我确信在我的计算机上只有这个程序正在运行,没有其他重要程序正在运行。我的问题是,如何确保我的测量准确且不受后台程序的影响,例如操作系统中断、调度、桌面渲染等。


我的第一个想法是观察可能干扰测量的每个可疑方面。

如果我担心中断,我应该在我的程序运行期间收集所有中断,并分析它们的开销。

如果我担心调度,我应该分析调度行为,以确保调度器不会产生额外的开销。

如果我担心我的程序使用 GPU 时的桌面渲染,桌面渲染也使用 GPU,最好禁用此渲染程序。

这有意义吗?还是有更好的方法?


相关问题:

How to get an accurate performance measure?

Getting reliable performance measurements for short bits of code

【问题讨论】:

只做一堆,除以次数。这样可以消除噪音。 @MikeDunlavey 这有点道理。但是,如果每次都出现噪音怎么办。 那么就OK了。这与在较慢的 CPU 上运行没有什么不同。 【参考方案1】:

您说得很好,操作系统中断、调度和许多其他事情都会影响您程序的性能。但请记住这一点:

当用时间来衡量复杂性之类的东西时,您并不是在寻找具体的衡量标准。假设您有一个在 O(n) 时间内运行的简单 for 循环,您想检查它并查看它运行了多长时间。如果您还没有看到时间复杂度,想象一下程序的复杂度与大小成正比,例如 10 个元素需要比 1 个元素“长”10 倍才能完成运行时间。当我说您不是在寻找特定的测量值时,我的意思是您正在寻找计算某些输入大小所需的时间比较与其他输入大小

因此,当您担心操作系统中断等问题时,我的建议是这样做:

如果您担心程序的效率,您可以测量它在多次运行过程中所花费的时间,以及几种输入大小。 例如,计算一个斐波那契数 100 次(相同的输入),然后计算完成每次运行所需的平均时间。

现在,将输入的大小增加到原始大小的两倍,然后再次执行一系列运行以获得平均运行时间。您会发现,平均而言,较大的输入将需要更长的计算时间。对所有大小的输入继续这样做,您实际上可以绘制每个输入大小的平均运行时间,这条曲线将大致代表您的算法复杂性。它不会是完美的,因为大多数实际函数不能用 O(n)、O(n^2) 来表示,会有一些系数可能会使曲线看起来很奇怪。

我希望这是有道理的,作为最后一点,请记住您应该指定您实际寻找的内容。听起来您正在尝试查找程序的运行时间,但是如果您不查看不同的输入大小,那又有什么意义呢?在没有比较的情况下查看特定时间(以实际秒为单位)有什么意义?在没有上下文的情况下显示一个程序在 1 秒内运行是非常没有意义的,所以我希望这篇文章可以让你更深入地了解如何以更传统的方式显示你的程序的性能。

【讨论】:

谢谢。关键不是时间复杂度,因为复杂程序的时间复杂度比斐波那契更难。相反,重点是如何“准确”测量程序运行时间。这意味着测量时间主要取决于程序,不包括操作系统。换句话说,如果程序在没有操作系统的机器上运行,那么这两个测量值应该不会相差太大。【参考方案2】:

我从Systems Benchmarking Crimes 中找到了几条基准测试规则:

    使用大量迭代。 检查标准偏差。如果 > 1%,请找出原因。 忽略最高点或最低点。 运行足够的未计时的预热迭代。

此外,根据一些网络搜索,将线程固定在特定内核上并设置进程的优先级可以消除调度影响。如果程序消耗的时间很短,比如几毫秒以下,可以考虑中断影响。否则可以忽略。

【讨论】:

以上是关于如何准确测量性能,排除后台程序干扰?的主要内容,如果未能解决你的问题,请参考以下文章

webstorm如何关闭后台进程

如何使 Java 桌面应用程序永远不会让系统休眠并在后台运行?

linux系统下如何从后台启动进程?

将应用程序带到前台时获取准确的坐标

通过android中的后台服务获取准确的路径历史

linux 让程序在后台运行的几种可靠方法