5

我有一个表现良好的例程。但是,我不得不对其进行更改。这一变化提高了例程的精度,但损害了性能。

该例程包含大量数学计算,并且可能是 CPU 绑定(我仍然需要对此进行更严格的测试,但我有 99% 的把握)。它是用 C++ 编写的(编译器是 Borland C++ 6)。

我现在想测量例程的性能,首先我考虑测量执行时间,但在我看来这是一种有缺陷的方法,因为可能会有更多的事情发生。

然后我遇到了这个话题:测量应用程序性能的技术 - 堆栈内存溢出。我喜欢通过 MFlops 进行测量的想法。

我的老板建议尝试通过 cpu 时钟周期进行某种测量,因此测试将与机器无关,但是,我认为这种方法属于 MFlops 测试。

在我看来,衡量这两件事(执行时间和 MFlops)是要走的路,但我想听听 stackoverflow 专家的意见。

测量被称为 CPU 绑定的例程性能的方法是什么?

4

6 回答 6

6

如果您的应用程序受内存限制,CPU 时钟周期也没有多大意义。在更快的 CPU 上,您将花费更多的 CPU 周期等待相同的缓存未命中。(数学应用程序可能不受 I/O 限制)。

另一个问题是特定指令序列的时钟周期数仍然会因架构而异(甚至包括 Intel Core1 / Core2 之间)。因此,作为性能的绝对衡量标准,一个 CPU 上的时钟周期几乎没有改进。

我会争辩说,作为衡量标准,它们实际上更糟。与时间不同,用户不关心周期。这对于现代多核 CPU 尤其重要。使用两倍周期数和 3 个内核的“低效”算法将在 67% 的时间内完成。用户可能会喜欢这样。

于 2009-06-12T14:44:52.277 回答
3

您的问题意味着该软件已经尽可能快,除了精度问题。我发现这种情况并不常见,我假设你真正想要的是让它那么快。

我建议测量没有抓住重点。

您真正需要做的是找到语句或指令(而不是函数)1)占挂钟时间的很大一部分,以及 2)您可以找到优化的方法。

假设该软件的规模不小,它可能至少有几层函数调用,并且很可能这些函数调用中的一些(不是函数,函数调用)负责显着的时间部分并且可以优化。

是一个很好的定位它们的方法,是一个使用它的例子。

于 2009-06-12T17:14:43.103 回答
2

我同意你老板的看法——以 CPU 时钟周期来衡量。请注意,可能还有其他事情正在发生,例如大量缓存未命中会减慢您的代码速度。如果可以,请使用 VTune 或英特尔的免费工具之一来查明瓶颈的性质。

于 2009-06-12T14:18:13.433 回答
2

如今,CPU 时钟周期不再与机器无关,即使 CPU 使用相同的指令集也是如此。x86(或其他)机器代码将以各种不同的方式进行切片和切块。这意味着任何事情的日子早已一去不复返了(而且,当 CPU 周期意味着什么的时候,有很多不同的 CPU 类型正在使用,以至于它无论如何都是依赖于机器的)。

更不用说受 CPU 限制的情况不像以前那么清楚了,缓存未命中等等。过去,受 CPU 限制的进程是仅受 I/O 等限制的进程,因为内存访问需要一定数量的 CPU 周期。

您要衡量的是性能,我认为这意味着它的运行速度。在这种情况下,您最好测量挂钟时间,重复计算足够多次以获得显着结果。您可以创建一个贯穿不同实现的测试工具,因此您将获得可比较的结果。

于 2009-06-12T17:30:12.160 回答
1

测量执行时间是要走的路。

在这种情况下,我认为您希望最小化您正在测量的内容以减少变量数量。

接下来,运行某种基线来校准特定机器将是一个好主意。要么使用最后签入的版本,要么使用某种与您尝试测量的计算类型大致匹配的密集例程。然后您可以将基准表示为

relative_time = measured_time_for_routine / measured_time_for_baseline
于 2009-06-12T17:18:59.083 回答
1

您可以根据 CPU 硬件计数器进行测量,VTune Intel 配置文件在这方面做得很好。它会根据 CPU 计数器(Instruction Retired、Cache Misses、Branch Mispredication)向您显示详细信息,它还会将这些信息与您函数中的每个语句相关联,因此您将对花费最多的内容有一个很好的了解。

这是假设您的函数不受内存限制。

谢谢

于 2009-06-14T06:36:07.537 回答