【问题标题】:Puzzle about the cache line padding关于缓存行填充的谜题
【发布时间】: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的时间比没有的多,缓存行填充的优势就体现不出来了。

【问题讨论】:

    标签: java caching


    【解决方案1】:

    VolatileLong 中看起来缺少的额外 8 个字节由object header 占用。所以VolatileLong的完整大小是64字节,即使在源代码中只有56字节可见。

    最后,使用正确的micro benchmark harness 执行测试以获得可靠的结果会更有效。

    【讨论】:

    • 我读过对象头,而我有一个 64 位架构,所以头占用了 16 位空间?所以在这个程序中,为了避免缓存行填充,我应该删除p6,对吗? @Kayaman
    • 这取决于您是否使用压缩的 OOP。它在链接的帖子中有所描述。
    猜你喜欢
    • 2017-10-19
    • 2020-05-09
    • 2013-05-14
    • 2016-04-01
    • 1970-01-01
    • 2022-08-14
    • 2013-06-17
    • 2017-11-02
    • 2011-09-17
    相关资源
    最近更新 更多