乱序硬件:它有多“智能”?

Posted

技术标签:

【中文标题】乱序硬件:它有多“智能”?【英文标题】:Out-of-order Hardware: How "smart" is it? 【发布时间】:2014-06-25 05:43:37 【问题描述】:

我正在从事一个对性能至关重要的项目,其中每个时钟周期都对我最重要的内部循环至关重要。我正在考虑重组代码以隐藏指令延迟,但我想知道现代 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;

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

现代主流无序硬件将在三个 add 指令之前重新排序 imul,即使 add 指令以编程方式位于 imul 之前,并且它们的所有输入依赖项都可以通过他们被解码的时间。 imuladd 指令具有更长的延迟,并且在依赖链中立即使用,因此这是最佳选择。

仅当由于缺少输入依赖项而解码时以编程方式执行的较早指令无法执行时,才会发生乱序执行。不能指望硬件“向前看”来动态优化这样的事情。

【问题讨论】:

我无法回答您的问题,但我猜它会根据实际 CPU 和所涉及的特定指令而有所不同。不过,编译器肯定会为您进行这种优化。 您会发现现代 x86 硬件非常能够在不存在分支错误预测的情况下跨大距离和跨循环迭代重新排序。 【参考方案1】:

您的第二个解释是正确的,乱序执行背后的想法是确保长依赖链或其他长时间运行的指令(如内存访问)不会阻塞独立操作(如两个与长时间运行的指令)并允许它们并行执行。但是,指令是按顺序获取和解码的。处理器无法提前查看程序,确定一条指令是独立的指令并在检索其他指令之前运行它。这就是编译器应该优化的地方。

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

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

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

【讨论】:

没有标量乱序的 x86 CPU。它们总是至少 2 宽(Bulldozer 系列的整数内核,Silvermont),更常见的是 4 宽(英特尔酷睿 2 到 Skylake)。或 5-wide (Ryzen)。因此,大多数现代 x86 CPU 可以在同一个周期内将所有 4 个微指令发送到无序后端,并在下一个周期将所有 4 个微指令分派到执行单元。 (假设它没有将多个之一安排到唯一的端口imul 可以运行...How are x86 uops scheduled, exactly?)。 但是,是的,发行后,他们以最旧的优先顺序发货。在大约第一次循环迭代之后,这通常优先考虑阻止退休的关键路径,但是将关键路径 uops 越早放置通常可能会更好,尤其是在非循环代码中,或者如果它不会运行多次迭代。

以上是关于乱序硬件:它有多“智能”?的主要内容,如果未能解决你的问题,请参考以下文章

15 同步于互斥 并发竞态和编译乱序执行乱序

怎样使数组元素乱序

js数组乱序输出 数组乱序排列

scrapy爬下来的数据是乱序的,如何排序?

171. 乱序字符串

171. 乱序字符串