内存屏障与 MESI 的关系是什么?
来源:1-14 Go 并发编程最佳实践
慕丝1411558
2021-06-18 18:27:29
看了好多文章,理解到“内存屏障”是提供主动调用刷新多级Cache、主存的一些指令,这样理解对么?
而MESI已经由CPU提供了缓存主存一致性方案了,那么他们俩的差别是什么呢?
可以理解成内存屏障是“主动”调用同步多级cache+主存,MESI是当产生cache miss时被动同步cache? 可以这样理解么?
内存屏障主要是用于一些update数据,先主动同步多级缓存与内存,减少之后cache miss导致的性能抖动?
2回答
另外,perfbook 的附录 C 中对 memory barrier 有非常详尽的说明~
如果想要完全理解还是得看这个(虽然他这个描述其实也已经简化很多了,真正的硬件提供的 barrier 更复杂,https://developer.arm.com/documentation/100941/0100/Barriers)
不过软件开发过程不用理解这么深,只要保证程序没有 race 就可以了~
Xargin
2021-06-19
Q: 看了好多文章,理解到“内存屏障”是提供主动调用刷新多级Cache、主存的一些指令,这样理解对么?
其实不太精确。。
内存屏障主要通过一些指令告诉 CPU/编译器(比如 mfence、lock 之类的),不要对这条指令和他前/后的读、写进行重排,从而保证并发编程的正确性。具体还分 read barrier,write barrier。
硬件和软件层的抽象也不太一样:
给应用程序员的抽象层:
内存屏障的应用抽象层比较好理解,就是四种情况:
四种 barrier 分别对应四种重排情况下的使用,都是防止相应的内存操作重排,注意,这里说的都是不同的变量,同一个变量的话,逻辑上有依赖关系,编译器/CPU 不会对其操作顺序进行重排。
在 Go 语言里,比如你用了 atomic.Cas,那这条指令前面的读、写操作都不会重排到这条指令之后。同时这条指令后面的读写都不会重排到这条指令之前。
其它语言里会有些区别~
实现的硬件层:
因为 mesi 协议的关系,变量的读写会有大量的同步,会导致 CPU 自己发生阻塞(详情可以看 perfbook 的 Appendix C 中的 Unnecessary Stalls)。为了优化阻塞,CPU 内部还设计了 store buffer 和 invalidate queue,相当于你的写操作和 cache 失效操作要在特定的队列里做缓存:
Many CPU architectures therefore provide weaker memory-barrier instructions that do only one or the other of these two. Roughly speaking, a “read memory barrier” marks only the invalidate queue and a “write memory barrier” marks only the store buffer, while a full-fledged memory barrier does both.
也就是说 read barrier (功能上要保证它前面所有的 read 都执行完)要把所有 invalidate 里的内容排空,write barrier 要把 store buffer 排空(功能上要保证它前面所有的 write 都执行完)。
个人感觉硬件实现对于软件工程师来说太难了。。你得把最底层的 read memory barrier 和上层编程语言提供的抽象再做一次关联:
上面这张图是 atomic 的 acquire 和 release 语义,这是软件层对硬件提供的 memory barrier 的又一次抽象。
对于我们应用层开发来说,知道内存屏障是用来防止重排的就行了~
Q: 而MESI已经由CPU提供了缓存主存一致性方案了,那么他们俩的差别是什么呢?
MESI 协议主要是为了在多核间同步单个变量的读、写操作,属于 cache coherence 范畴;
内存屏障是为了解决在多核乱序执行(主要因为 CPU 中的 store buffer 和 invalidate queue)时,防止某些并发场景的内存重排的工具,解决的是多个不同变量的读、写顺序问题,属于 memory consistency 范畴;
Q: 可以理解成内存屏障是“主动”调用同步多级cache+主存,MESI是当产生cache miss时被动同步cache? 可以这样理解么?
不太一样~看上面的解释
Q: 内存屏障主要是用于一些update数据,先主动同步多级缓存与内存,减少之后cache miss导致的性能抖动?
内存屏障主要是为了解决并发时的顺序问题,和性能没关系~
相似问题