gpt4 book ai didi

java - StoreStore 屏障如何映射到 x86 下的指令?

转载 作者:行者123 更新时间:2023-11-30 10:49:45 25 4
gpt4 key购买 nike

JSR133 cookbook说:

StoreStore Barriers The sequence: Store1; StoreStore; Store2 ensures that Store1's data are visible to other processors (i.e., flushed to memory) before the data associated with Store2 and all subsequent store instructions. In general, StoreStore barriers are needed on processors that do not otherwise guarantee strict ordering of flushes from write buffers and/or caches to other processors or main memory.

并且,从食谱中我们知道,对于同步块(synchronized block),Java 编译器将插入一些屏障以防止可能的重新排序:

MonitorEnter
[LoadLoad] <==inserted barrier
[LoadStore]<==inserted barrier

...
[LoadStore]<==inserted barrier
[StoreStore]<==inserted barrier
MonitorExit

但是,由于 x86 不允许重新排序 Read-Read、Read-Write 和 Write-Write。所以上面所有的barrier都会映射到no-ops。这相当于说对于x86处理器,MonitorEnter和MonitorExit之间不会插入barriers。我的困惑是,如果我们将 StoreStore 映射到 x86 下的空操作,那么如何保证可见性?更详细地说,x86 确实使用了存储缓冲区,因此为了使在临界区执行的写入对其他处理器可见,我们需要刷新存储缓冲区,因此需要一个写屏障。从可见性的角度a应该映射到sfence/mfence/Lock#?但是菜谱上说,从防止重新排序的角度来看,它应该映射到 no-op。或者,关键点是可见性保证是由 MonitorEnter 和MonitorExit 本身?如果是这样,我想他们可能会使用所谓的 Read barrier 和 Write barrier 来保证可见性,对吧?

最佳答案

尽管我们可以说内存屏障能够:

  1. 保证可见性(通过刷新存储缓冲区和/或应用使队列无效)
  2. 防止重新排序(禁止加载之间重新排序 和/或存储在内存屏障之前或之后)

但这并不意味着内存屏障应该总是同时做以上两件事,Sun JDK 提供的 Unsafe.doPutOrderedXX 方法就是这样一个例子:

SomeClass temp = new SomeClass(); //S1
unsafe.putOrderedObject(this, valueOffset, null);
Object target = temp; //S2

unsafe.putOrderedObject 在这里用作 StoreStore 屏障,因此可以防止S1 和 S2 的重新排序,但它不保证 S1 的结果对其他处理器/线程可见(因为没有这样的需要)。

关于 Unsafe 和 volatile 的更多信息:

  1. Where is sun.misc.Unsafe documented?

  2. http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/

  3. http://jpbempel.blogspot.com/2013/05/volatile-and-memory-barriers.html

也就是说,在x86下,为了enter code here防止重排序,一个StoreStore可以映射到no-op,为了保证可见性,一个StoreStore应该映射到一些指令,如 sfence/mfence/LOCK#。

另一个例子是final关键字。为了强制执行 final 的语义(无法更改观察到的变量的值),编译器应该在写入 final 字段和从该构造函数返回之间插入一个 StoreStore 屏障。原因要做到这一点是:在将构造对象的引用写入引用变量之前,确保写入 final 字段应该对其他处理器可见。实际上,这意味着需要顺序而不是可见性,因此不需要在返回之前刷新(flushing Store Buffer/or Cache)final 的结果来自那个构造函数。因此,在 x86 下,JVM 不会为 final 字段插入任何屏障。

关于java - StoreStore 屏障如何映射到 x86 下的指令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35309874/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com