0

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

我更多地考虑指令吞吐量?我怎么能写出这样的工具?这有没有可能?

4

3 回答 3

4

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

于 2013-07-17T20:51:08.793 回答
3

好吧,你可以,但它的相关性非常有限。您无法仅通过查看说明来判断运行时间。

  • 缓存使用情况如何?“更长”的代码对缓存更友好,因此速度更快。

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

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

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

编辑 2:忘记在第二点中包含乱序案例。

于 2013-07-17T20:56:24.840 回答
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 等价物,但如果有的话,我很想听听。

于 2013-07-19T06:34:35.793 回答