【发布时间】:2018-01-11 22:05:10
【问题描述】:
我读过一篇关于缓存行填充的文章,网址是: https://mechanical-sympathy.blogspot.com/2011/07/false-sharing.html
它有一个这样的例子:
public final class FalseSharing implements Runnable {
public final static int NUM_THREADS = 4; // change
public final static long ITERATIONS = 500L * 1000L * 1000L;
private final int arrayIndex;
private static VolatileLong[] longs = new VolatileLong[NUM_THREADS];
static {
for (int i = 0; i < longs.length; i++) {
longs[i] = new VolatileLong();
}
}
public FalseSharing(final int arrayIndex) {
this.arrayIndex = arrayIndex;
}
public static void main(final String[] args) throws Exception {
final long start = System.nanoTime();
runTest();
System.out.println("duration = " + (System.nanoTime() - start));
}
private static void runTest() throws InterruptedException {
Thread[] threads = new Thread[NUM_THREADS];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new FalseSharing(i));
}
for (Thread t : threads) {
t.start();
}
for (Thread t : threads) {
t.join();
}
}
public void run() {
long i = ITERATIONS + 1;
while (0 != --i) {
longs[arrayIndex].value = i;
}
}
public final static class VolatileLong {
public volatile long value = 0L;
public long p1, p2, p3, p4, p5, p6; // comment out
}
}
问题 1: 如果我想避免虚假共享,我应该确保 VolatileLong 对象是 64 字节,长值 0L 是 8 字节,p1、p2、p3、p4、p5、p6 是 48 字节,那么剩下的 8 字节究竟是什么?
问题 2: 我已经执行了这个程序,结果是:22951146607 如果我删除 VolatileLong 中的变量 p6,结果是:19457942328,它比 p6 少,而如果没有 p6,它应该会遭受错误共享。当然每次结果都不一样,但是通常有p6的时间比没有的多,缓存行填充的优势就体现不出来了。
【问题讨论】: