You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: md/05内存模型与原子操作.md
+11-3Lines changed: 11 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -313,19 +313,27 @@ void f(){
313
313
314
314
-**CPU 与编译器不是神经病,没有*好处*不会闲的没事给你指令重排**。
315
315
316
+
---
317
+
318
+
- 编译器重排:编译器在编译代码时,为了提高性能,可以按照一定规则重新安排代码的执行顺序。例如,可以将不相关的指令重排,使得 CPU 流水线更加高效地执行指令。编译器优化需要遵守一个“[**如同规则**](https://zh.cppreference.com/w/cpp/language/as_if)(as-if rule)”,即不可改变可观察的副作用。
319
+
320
+
- CPU 重排:CPU 在运行程序时,也会对指令进行重排,以提高执行效率,减少等待时间。这种重排通常遵循一些硬件层面的优化规则,如内存访问的优化。
321
+
316
322
你们可能还有疑问:“**单线程能不能指令重排**?”
317
323
318
-
其实完全是可以的,只不过不用在乎,不过我们还是可以稍微聊一下。用一个极端的例子来说:
324
+
CPU 的指令重排必须遵循一定的规则,以确保程序的可观察副作用不受影响。对于单线程程序,CPU 会保证外部行为的一致性。对于多线程程序,需要开发者使用同步原语来显式地控制内存操作的顺序和可见性,确保多线程环境下的正确性。而标准库中提供的原子对象的原子操作,还可以设置内存次序。
325
+
326
+
那有没有可能:
319
327
320
328
- “*end 重排到 start 前面了!指令重排了!*”
321
329
322
-
有可能吗?完全有可能。但这也就是前面说的,把 CPU 与编译器当神经病。首先编译器优化需要遵守一个“[**如同规则**](https://zh.cppreference.com/w/cpp/language/as_if)(as-if rule)”,即不可改变可观察的副作用(简单来说编译器优化不该影响程序可观测的结果)。另外 CPU 也有类似,不然各位写代码难道还要考虑下面这里,会不会指令重排导致先输出 `end` 吗?这显然不现实。
330
+
这也就是前面说的,把 CPU 与编译器当神经病。各位写代码难道还要考虑下面这段,会不会指令重排导致先输出 `end` 吗?这显然不现实。
323
331
324
332
```txt
325
333
print("start"); // 1
326
334
print("end"); // 2
327
335
```
328
336
329
-
但是为什么我说有可能呢?因为不禁止就是有可能,但是我们无需在乎,**就算真的 end 重排到 start 前面了,也得在可观测行为发生前回溯了**。所以我一直在强调,这些东西,**我们无需在意**。
337
+
不禁止就是有可能,但是我们无需在乎,**就算真的 CPU 将 end 重排到 start 前面了,也得在可观测行为发生前回溯了**。所以我一直在强调,这些东西,**我们无需在意**。
0 commit comments