多线程和乱序执行
假设我们有一个多线程 C 程序(pthreads),并且编译器不会对各个线程的(不同步)共享变量访问进行重新排序。 x86 CPU 是否尊重共享变量访问的顺序(在单个线程内),或者它是否有可能重新排序某些内存访问?
Assume we have a multithreaded C program (pthreads), and the (unsynchronized) shared variable accesses of the individual threads are not reordered by the compiler. Does an x86 CPU respect the order of the shared variable accesses (within a single thread), or is it possible that it reorders some memory accesses?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
<罢工>
不同步的共享变量访问是危险的,无序是其原因之一。
x86 保持按顺序写入(在线程内),但不按顺序读取。
如果您假设顺序保持不变,这可能会给您带来麻烦。例如:
线程 A 写入 x,然后写入 y。假设编译器没有对其重新排序,CPU 就不会对其进行重新排序(x86 不会,其他可能会)。
线程 B 读取 y,然后读取 x。你可能会认为,如果它得到了 y 的新值,那么你肯定也会得到 x 的新值。
并非如此。 CPU 可能会重新排序线程 B 的读取,因此 y 实际上会更早读取。
编辑:正如“Man of One Way”指出的那样,在这种情况下,x86(但不是所有处理器!)保证顺序。
我引用Intel软件开发人员手册:
对于多个处理器的写入来说,情况并非如此 - 不同处理器的写入顺序似乎不同。
但是,我强烈建议不要依赖它,而是使用正确的同步。
同步原语是通过原子操作和/或屏障来实现的,这可以保证您的安全。
Unsynchronized shared variable accesses are dangerous, and out-of-order is one reason for it.
The x86 keeps writes in order (within a thread), but not reads.
This can get you into trouble, if you assume the order remains. For example:
Thread A writes to x and then to y. Assuming the compiler didn't reorder it, the cpu won't reorder it (x86 won't, others might).
thread B reads y and then x. You might think that if it got y's new value, then surely you'll get x's new value as well.
Not so. The CPU may reorder thread B's reads, so y will be actually read earlier.
EDIT: as "Man of One Way" pointed out, in this case, x86 (but not all processors!) guarantees ordering.
I quote the Intel software developer's manual:
This isn't true for writes by multiple processors - they may seem to be ordered differently by different processors.
However, I highly recommend not relying on it, and using use proper synchronization instead.
The synchronization primitives are implemented with atomic operations and/or barriers, which keep you safe.
由于存储缓冲区的存在,某些重新排序是可能的。参见例如 https://www.cl.cam.ac.uk/ ~pes20/weakmemory/cacm.pdf
但是,仅在多个线程中才能看到重新排序,在单个线程中,来自该线程的所有访问似乎都是按顺序发生的。
Some reorderings are possible, due to the presence of a store buffer. See e.g. https://www.cl.cam.ac.uk/~pes20/weakmemory/cacm.pdf
However, the reorderings are seen only with several threads, within a single thread all accesses from that thread appear to happen in order.