我读过一篇有关缓存行填充的文章,网址是:
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的时间比不使用p6的时间更多,这并没有显示出缓存行填充的优势。

最佳答案

VolatileLong缺少的另外8个字节由object header占用。因此,即使在源代码中仅可见56个字节,VolatileLong的总大小为64个字节。

最后,以适当的micro benchmark harness进行测试以获得可靠的结果会更加有效。

08-06 06:40