简体   繁体   English

关于缓存行填充的困惑

[英]Puzzle about the cache line padding

I've read an article about cache line padding, the url is : https://mechanical-sympathy.blogspot.com/2011/07/false-sharing.html 我已经阅读了有关缓存行填充的文章,其网址为: https : //mechanical-sympathy.blogspot.com/2011/07/false-sharing.html

It has an Example like this: 它有一个像这样的例子:

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
    }
}

Question 1: If I want to avoid false sharing, I should make sure the VolatileLong object is 64 bytes, the long value 0L is 8 bytes, p1, p2, p3, p4, p5, p6 are 48 bytes, then what is the rest 8 bytes exactly? 问题1:如果要避免错误共享,应确保VolatileLong对象为64个字节,长值0L为8个字节,p1,p2,p3,p4,p5,p6为48个字节,剩下的是什么到底是8个字节?

Question 2: I've executed this program, the result is:22951146607 If I remove the variable p6 in VolatileLong, the result is: 19457942328, it's less than with p6, while it's supposed to suffer from false sharing for without p6. 问题2:我已经执行了该程序,结果是:22951146607如果我在VolatileLong中删除变量p6,结果是:19457942328,它小于带p6的值,而如果不带p6,则应该遭受错误共享。 Of course, the result is different every time, but usually the time with p6 is more than without, it doesn't show the advantage for cache line padding. 当然,每次的结果都是不同的,但是通常使用p6的时间要比不使用p6的时间多得多,这并没有显示出缓存行填充的优势。

The additional 8 bytes that looks like it's missing from VolatileLong is taken by the object header . 对象标头占据了VolatileLong中似乎缺少的其他8个字节。 So the full size of VolatileLong is 64 bytes, even if only 56 bytes are visible in the source code. 因此,即使源代码中只有56个字节可见, VolatileLong大小为64个字节。

Lastly it would be more efficient to perform the testing with a proper micro benchmark harness to get reliable results. 最后,使用适当的微基准测试工具进行测试以得到可靠的结果会更有效率。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM