测量快速代码的性能/吞吐量忽略处理器速度?

时间:2013-07-17 20:47:24

标签: c++ performance optimization assembly cpu

有没有办法可以编写一个“工具”,它可以从C / C ++程序中分析生成的x86汇编语言,并以这种方式测量性能,如果我在1GHz或3GHz上运行它就没关系处理器?

我在更多地考虑指令吞吐量?我怎么能写这样的工具?会不可能?

3 个答案:

答案 0 :(得分:4)

我很确定这必须等同于暂停问题,在这种情况下无法完成。分支预测,内存访问和内存缓存等都会改变性能,无论程序运行的CPU速度如何。

答案 1 :(得分:3)

嗯,你可以,但它的相关性非常有限。只需查看说明,就无法告诉运行时间。

  • 缓存使用情况如何? “更长”的代码可以更加缓存,因此更快。

  • 某些CPU指令可以并行和无序执行,但最终行为很大程度上取决于硬件。

如果你真的想尝试一下,我建议你为valgrind编写一个工具。您基本上可以在模拟环境下运行程序,确保您可以复制真实CPU的行为(这是具有挑战性的部分)。

编辑:为了清楚起见,我假设你想要从真实输入中提取动态分析。如果你想进行静态分析,你将会处于“不可判断的土地”中,正如另一个答案所指出的那样(你甚至无法检测给定的代码是否永远循环)。

编辑2:忘记在第二点包括无序案例。

答案 2 :(得分:1)

这是可能的,但前提是该工具知道处理器的所有内部构件,它正在为其预测性能。因为知道“所有”内部结构等于构建自己的处理器,所以你会正确地猜测这不是一件容易的事。相反,你需要做出很多假设,并希望它们不会过多地影响你的答案。不幸的是,对于长度超过几百条指令的任何事情,这些假设(例如,所有内存读取都在L1数据高速缓存中找到并且具有4个周期延迟;所有指令都在L1指令高速缓存中但之后在跟踪高速缓存中)会影响您的答案很多。时钟速度可能是最容易处理的变量,但其余部分的细节因处理器而异。

当前处理器是“推测性的”,“超标量”和“无序”。推测意味着他们在计算正确选择之前选择他们的代码路径,然后如果猜测错误则返回并从分支重新开始。超标量意味着有时可以同时执行多个不相互依赖的指令 - 但仅限于某些组合。乱序意味着有一个指令池等待执行,处理器根据输入准备好的时间选择何时执行它们。

更糟糕的是,指令不会立即执行,并且它们所执行的周期数(以及它们在此期间占用的资源)也会发生变化。分支预测的准确性很难预测,处理器恢复需要不同的周期数。缓存是不同的大小,需要不同的时间来访问,并具有不同的算法来决定缓存什么。在没有引用它正在执行的处理器的情况下,没有任何有意义的“程序集执行速度”的概念。

但这并不意味着你无法推理它。您可以越多地缩小目标处理器的范围,并且对正在评估的代码的约束越多,就越能预测代码的执行方式。 Agner Fog对当前一代x86处理器的差异和相似之处进行了很好的中级介绍: http://www.agner.org/optimize/microarchitecture.pdf

此外,英特尔免费提供一个非常有用(并且令人惊讶的未知)工具,可以为最近几代的处理器解决很多这些问题。如果您试图在紧密循环中测量几十个指令的性能和交互,IACA可能已经做了您想要的。可以对数据的界面和表示进行各种改进,但在尝试编写自己的数据之前绝对值得一试:

http://software.intel.com/en-us/articles/intel-architecture-code-analyzer

据我所知,没有AMD等价物,但如果有,我很乐意听到它。