Linux kernel 屏障后的写入程序如何在屏障前的写入程序之前可见?
在linux内核的内存屏障文档(documentation/memory barriers.txt)中,有一些示例显示,内存屏障之后的写入程序在内存屏障之前对其他CPU的写入之前是可见的。这怎么会发生?为什么写入障碍不足以对这些写入进行排序 特别是:Linux kernel 屏障后的写入程序如何在屏障前的写入程序之前可见?,linux-kernel,shared-memory,memory-model,Linux Kernel,Shared Memory,Memory Model,在linux内核的内存屏障文档(documentation/memory barriers.txt)中,有一些示例显示,内存屏障之后的写入程序在内存屏障之前对其他CPU的写入之前是可见的。这怎么会发生?为什么写入障碍不足以对这些写入进行排序 特别是: 843 CPU 1 CPU 2 844 ======================= ======================= 845 {
843 CPU 1 CPU 2
844 ======================= =======================
845 { B = 7; X = 9; Y = 8; C = &Y }
846 STORE A = 1
847 STORE B = 2
848 <write barrier>
849 STORE C = &B LOAD X
850 STORE D = 4 LOAD C (gets &B)
851 LOAD *C (reads B)
852
853 Without intervention, CPU 2 may perceive the events on CPU 1 in some
854 effectively random order, despite the write barrier issued by CPU 1:
855
856 +-------+ : : : :
857 | | +------+ +-------+ | Sequence of update
858 | |------>| B=2 |----- --->| Y->8 | | of perception on
859 | | : +------+ \ +-------+ | CPU 2
860 | CPU 1 | : | A=1 | \ --->| C->&Y | V
861 | | +------+ | +-------+
862 | | wwwwwwwwwwwwwwww | : :
863 | | +------+ | : :
864 | | : | C=&B |--- | : : +-------+
865 | | : +------+ \ | +-------+ | |
866 | |------>| D=4 | ----------->| C->&B |------>| |
867 | | +------+ | +-------+ | |
868 +-------+ : : | : : | |
869 | : : | |
870 | : : | CPU 2 |
871 | +-------+ | |
872 Apparently incorrect ---> | | B->7 |------>| |
873 perception of B (!) | +-------+ | |
874 | : : | |
875 | +-------+ | |
876 The load of X holds ---> \ | X->9 |------>| |
877 up the maintenance \ +-------+ | |
878 of coherence of B ----->| B->2 | +-------+
879 +-------+
880 : :
881
882
883 In the above example, CPU 2 perceives that B is 7, despite the load of *C
884 (which would be B) coming after the LOAD of C.
843 CPU 1 CPU 2
844 ======================= =======================
845{B=7;X=9;Y=8;C=&Y}
846商店A=1
847商店B=2
848
849存储C=&B加载X
850存储D=4加载C(获取和保存)
851负载*C(读数为B)
852
853在没有干预的情况下,CPU 2可以在某些情况下感知CPU 1上的事件
854有效的随机顺序,尽管CPU 1发出写屏障:
855
856 +-------+ : : : :
857更新的顺序
858||-->|B=2|-->|Y->8|
859 | |:-+---+\+----++----+| CPU 2
860 | CPU 1 |:| A=1 | \-->| C->&Y | V
861 | | +------+ | +-------+
862 | | wwwwwwwwwwww |::
863 | | +------+ | : :
864 | | | C=&B |--|::+-------+
865 | | : +------+ \ | +-------+ | |
866 | |-->| D=4 |-->| C->&B |-->||
867 | | +------+ | +-------+ | |
868 +-------+ : : | : : | |
869 | : : | |
870 |::| CPU 2|
871 | +-------+ | |
872明显不正确-->|B->7-->||
873对B的知觉(!)|+----+||
874 | : : | |
875 | +-------+ | |
876 X的负载保持-->\\\\124; X->9-->\|
877增加维护\+---+||
878关于B的相干性------->B->2+-------+
879 +-------+
880 : :
881
882
883在上述示例中,尽管负载为*C,但CPU 2感知到B为7
884(即B)在加载C之后出现。
写入屏障没有正确地排列写入顺序
正如下面的文本所解释的,问题在于CPU 2可以在
C
之前读取*C
,因为它不使用任何类型的读取障碍。一篇更好的关于内存障碍的文章是,因为存在隐式数据依赖关系(您只能在读取C之后读取*C),所以仍然不清楚这是如何发生的。啊,这是清楚的。该示例试图解释在没有数据依赖性障碍的情况下可能发生的情况。谢谢对*C
的读取可以提前推测,并且可能已经在缓存中。