无序硬件:它的“智能”程度如何?

问题描述 投票:3回答:1

我正在开展一个令人难以置信的性能关键项目,每个时钟周期都在我最重要的内循环中。我正在考虑重构代码以隐藏指令延迟,但我想知道现代CPU的无序执行硬件在多大程度上已经为我做了这个。考虑以下(简单,假设)示例:

// Increment three counters.  These instructions should all execute in
// parallel with latency of one cycle.  Assume the previous register values
// have been computed a long time ago and are ready to use by the time
// these are decoded.
add RAX, 1;
add RBX, 2;
add RCX, 3;

// Multiply takes at least three cycles.  Again, assume both inputs are
// ready by the time we get here.
imul RDX, RDI;

// Use the result of the imul immediately in a long dependency chain.
mov RDX, [RDX];
cmp RDX, 1;
jae LBlahBlahBlah;

我的问题是以下哪项适用:

  • 现代主流无序硬件将在三个imul指令之前重新排序add,即使add指令以编程方式出现在imul之前,并且在它们被解码时具有所有输入依赖性。 imul具有比add指令更长的延迟,并且在依赖链中立即使用,因此这是最佳的。
  • 当由于缺少输入依赖性而在解码时无法执行编程上较早的指令时,才会发生乱序执行。不能期望硬件“向前看”以便在运行中优化这样的事情。
performance optimization x86-64 low-level order-of-execution
1个回答
2
投票

你的第二种解释是正确的,无序执行背后的想法是确保长依赖链或其他长时间运行的指令(如内存访问)不阻止独立操作(如两个与长时间运行无关的寄存器之间的添加)指令)并允许它们并行执行。但是,指令是按顺序获取和解码的。处理器无法预览程序,决定一条指令是独立的,并在检索其他指令之前运行它。这就是编译器想要优化的地方。

在你的例子中,指令是按顺序获取和解码的,首先是add RAX, 1,然后是add RBX, 2,然后是add RCX, 3,然后是imul RDX, RDI(尽管如果处理器是超级分类器,你可以获取和解码多个,但这是一个单独的概念)。每个都将依次发送到适当的保留站,但是,如果只有一个单元来执行添加,则会出现无序方面,一些添加可能与imul同时执行;这是非常的架构依赖。

如果时间要求的细节如此严格,您将需要非常小心现代的高速架构,因为它们具有大量复杂的结构以提高性能。但是,根据代码运行,这些机制可能会导致严重的延迟。在错误或错误预测的情况下,分支预测和缓存只是延迟的两个来源(或正确使用时的良好吞吐量改进)。最好的办法是获得一个周期精确的处理器模拟器,以确保您的代码符合要求(或者您可以使用实际的硬件)。

另请注意,如果您使用的是现代架构,我假设您可能正在运行操作系统,这是一个软件级别,会破坏您试图达到的超高性能。

© www.soinside.com 2019 - 2024. All rights reserved.