为什么单核CPU不会出现指令重排序问题?

问题描述 投票:0回答:2

来自这个帖子

在单个 CPU 核心上对两个线程进行时间切片不会遇到重新排序问题。单个核心始终了解其自身的重新排序,并将正确解析其自己的所有内存访问。然而,多个核心在这方面独立运行,因此不会真正了解彼此的重新排序。

为什么指令重排序问题不能发生在单CPU核心上?这篇文章不解释。

示例
以下图片摘自行为中的记忆重组

以下为记录:

我认为记录的指令也可能在单个CPU上引起问题,因为

r1
r2
都不是
1

multithreading memory multiprocessing cpu-architecture memory-barriers
2个回答
3
投票

单个核心始终了解其自身的重新排序,并将正确解决其自己的所有内存访问。

单个CPU核心重新排序,但它知道它自己的重新排序,并且可以采取巧妙的技巧来假装它没有重新排序。因此,事情进展得更快,没有奇怪的副作用。

然而,多个核心在这方面独立运行,因此不会真正了解彼此的重新排序。

当一个CPU重新排序时,其他CPU无法对此进行补偿。想象一下,如果 CPU #1 正在等待对变量 A 的写入,然后它会从变量 B 中读取。如果 CPU#2 写入变量 B,然后写入变量 A,如代码所示,不会出现问题。如果CPU#2重新排序以首先写入变量A,则CPU#1不知道并尝试在变量B有值之前读取它。这可能会导致崩溃或任何“随机”行为。 (英特尔芯片有更多魔力让这种情况不会发生)

在单个 CPU 核心上对两个线程进行时间切片不会遇到重新排序问题。

如果两个线程都在同一个CPU上,那么写入发生的顺序并不重要,因为如果它们被重新排序,那么它们都在进行中,并且CPU不会真正切换,直到两者都被写入,在这种情况下,它们可以安全地从另一个线程读取。

示例

如果代码在单核上出现问题,则必须重新排列进程 1 中的两条指令 被进程 2 中断并在这两条指令之间执行。但如果在它们之间被中断,它知道它必须中止它们,因为它知道它自己的重新排序,并且知道它处于危险状态。因此,它要么按顺序执行它们,要么在切换到进程 2 之前执行这两项操作,或者在切换到进程 2 之前都不执行任何操作。所有这些都避免了重新排序问题。


2
投票

有多种效果在起作用,但它们仅被建模为一个效果。更容易推理它们。是的,现代核心已经自行重新排序指令。但它维持它们之间的逻辑流,如果两条指令之间具有相互依赖性,那么它们将保持有序,因此程序的逻辑不会改变。发现这些相互依赖关系并防止过早发出指令是执行引擎中重新排序缓冲区的工作。

这个逻辑是可靠的、可靠的,否则几乎不可能编写程序。但内存控制器无法提供同样的保证。它具有让多个处理器访问同一共享内存的令人羡慕的工作。

首先是预取器,它提前从内存中读取数据,以确保在执行读指令时数据可用。确保核心不会因等待读取完成而停止。问题在于,由于内存被提前读取,因此在预取完成和读取指令执行之间,它可能是另一个核心更改的陈旧值。对于外部观察者来说,该指令看起来像是提前执行的。

存储缓冲区,它获取写入指令的数据并将其延迟写入内存。后来,指令执行后。确保内核不会停止等待内存总线写入周期完成。对于外部观察者来说,它看起来就像指令执行较晚。

将预取器和存储缓冲区的效果建模为指令重新排序效果非常方便。您可以轻松地将其写在一张纸上并推理出副作用。

对于核心本身来说,预取器和存储缓冲区的影响完全是良性的,并且核心不会注意到它们。只要没有另一个核心也在改变内存内容。单核机器总是有这样的保证。

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