gpt4 book ai didi

java - 为什么java的Exchanger.Slot cache line padding是这样的?

转载 作者:搜寻专家 更新时间:2023-11-01 03:48:33 29 4
gpt4 key购买 nike

当我阅读 java 中的“虚假共享”机制时,我在 java.util.concurrent.Exchanger.Slot 中找到了以下代码

    /**
* A Slot is an AtomicReference with heuristic padding to lessen
* cache effects of this heavily CAS'ed location. While the
* padding adds noticeable space, all slots are created only on
* demand, and there will be more than one of them only when it
* would improve throughput more than enough to outweigh using
* extra space.
*/
private static final class Slot extends AtomicReference<Object> {
// Improve likelihood of isolation on <= 64 byte cache lines
long q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe;
}

奇怪,为什么long的个数是15(q0 - qe),所以我可以计算出对象的大小应该是:
15 * 8 (long) + 8 (parent's long value) + 16 (object header pointer at 64 bit jvm) = 144 byte.
或者:
15 * 8 (long) + 8 (parent's long value) + 8 (object header pointer at 32 bit jvm) = 136 byte.
当我阅读 Disruptor's implemention:

public long p1, p2, p3, p4, p5, p6, p7; // cache line padding

private volatile long cursor = INITIAL_CURSOR_VALUE;

public long p8, p9, p10, p11, p12, p13, p14; // cache line padding

大小应该是 7*8 + 8 + 7*8 + 8(object head opinter'size at 32 bit jvm)= 128 = 64 * 2。
由于大多数 cpu 的默认缓存行大小为 64 字节,因此 discruptor 的 impl 可以避免“虚假共享”。
所以我的问题是在类里面填充了多少个longjava.util.concurrent.Exchanger.Slot 是对还是错?

最佳答案

java.util.concurrent.Exchanger.Slot 中的填充是安全的。它正在添加额外的填充,而另一方面,破坏者添加的恰到好处。

如果 JVM 重新排序字段并且缓存行大小为 128 位,则中断方法也可能会失败。最安全的做法是通过继承来分隔字段:

class MemoryFieldAddress {
private long address;

public final long getAddress() {
return address;
}

protected final void setAddress(final long address) {
this.address = address;
}
}

class MemoryAddressPad1 extends MemoryFieldAddress {
long p1_1, p1_2, p1_3, p1_4, p1_5, p1_6, p1_7, p1_8, p1_9, p1_10, p1_11, p1_12, p1_13, p1_14, p1_15, p1_16, p1_17;
}

class MemoryFieldBytes extends MemoryAddressPad1 {
private long bytes;

public final long getBytes() {
return bytes;
}

protected final void setBytes(final long bytes) {
this.bytes = bytes;
}
}

class MemoryAddressPad2 extends MemoryFieldBytes {
long p2_1, p2_2, p2_3, p2_4, p2_5, p2_6, p2_7, p2_8, p2_9, p2_10, p2_11, p2_12, p2_13, p2_14, p2_15, p2_16, p2_17;
}

// Finally the full implimentation
public class Memory extends MemoryAddressPad2 {}

如果您愿意,可以将最终字段和很少更新的字段计入填充。

关于java - 为什么java的Exchanger.Slot cache line padding是这样的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35605860/

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