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
2.**内存次序错误的使用难以察觉**:即使通过多次(数以万计)运行也难以发现。这是因为许多内存次序问题是由于极端的、少见的情况下的竞争条件引起的,而这些情况很难被重现。此外,即使程序在某些平台上运行正常,也不能保证它在其他平台上也能表现良好,因为不同的 CPU 和编译器可能对内存操作的顺序有不同的处理(例如 x86 架构内存模型:Total Store Order (TSO),是比较严格的内存模型)。因此,开发者必须依赖自己的知识和经验,以及可能的测试和调试技术,来发现和解决内存次序错误。
311
+
312
+
造成错误难以被我们观察到的原因很朴素:
313
+
314
+
-**CPU 与编译器不是神经病,没有*好处*不会闲的没事给你重排**。
315
+
316
+
你们可能还有疑问:“**单线程能不能指令重排**?”
317
+
318
+
其实完全是可以的,只不过不用在乎,不过我们还是可以稍微聊一下。用一个极端的例子来说:
319
+
320
+
- “*end 重排到 start 前面了!指令重排了!*”
321
+
322
+
有可能吗?完全有可能。但这也就是前面说的,把 CPU 与编译器当神经病。首先编译器优化需要遵守一个“如同规则”,即不可改变可观察的副作用(简单来说编译器优化不该影响程序结果)。另外 CPU 也有类似,不然各位写代码难道还要考虑下面这里,会不会指令重排导致先输出 `end` 吗?这显然不现实。
323
+
324
+
```txt
325
+
print("start"); // 1
326
+
print("end"); // 2
327
+
```
328
+
329
+
但是为什么我说有可能呢?因为不禁止就是有可能,但是我们无需在乎,**就算真的 end 重排到 start 前面了,也得在可观测行为发生前回溯了**。所以我一直在强调,这些东西,**我们无需在意**。
0 commit comments