【CacheLine】关于缓存行的笔记(存疑)

什么是缓存行

Cache是由很多个cache line组成的。每个cache line通常是64字节,并且它有效地引用主内存中的一块儿地址。一个Java的long类型变量是8字节,因此在一个缓存行中可以存8个long类型的变量。

CPU每次从主存中拉取数据时,会把相邻的数据也存入同一个cache line。

在访问一个long数组的时候,如果数组中的一个值被加载到缓存中,它会自动加载另外7个。因此你能非常快的遍历这个数组。事实上,你可以非常快速的遍历在连续内存块中分配的任意数据结构。

下面的例子是测试利用cache line的特性和不利用cache line的特性的效果对比。

代码示例来源于:https://tech.meituan.com/2016/11/18/disruptor.html

public class CacheLineEffect {

    //考虑一般缓存行大小是64字节,一个 long 类型占8字节
    static  long[][] arr;
    static int size = 8;

    public static void main(String[] args) {
        arr = new long[1024 * 1024][];
        for (int i = 0; i < 1024 * 1024; i++) {
            arr[i] = new long[size];
            for (int j = 0; j < size; j++) {
                arr[i][j] = 0L;
            }
        }
        long sum = 0L;
        long marked = System.currentTimeMillis();
        for (int i = 0; i < 1024 * 1024; i+=1) {
            for(int j =0; j< size;j++){
                sum = arr[i][j];
            }
        }
        System.out.println("Loop times:" + (System.currentTimeMillis() - marked) + "ms");

        marked = System.currentTimeMillis();
        for (int i = 0; i < size; i+=1) {
            for(int j =0; j< 1024 * 1024;j++){
                sum = arr[j][i];
            }
        }
        System.out.println("Loop times:" + (System.currentTimeMillis() - marked) + "ms");
    }
}

在本机上测试的结果:
Loop times:12ms
Loop times:45ms


按上面的例子,一般来说,两层的for循环,是希望外层少,内层多。
但尝试了一下,这个理论用在这里貌似并不适用。
即使 size 不是8, 换成10之后,也还是一样,仿佛并没有证明到缓存行的效果?
反倒是 两层 for 循环的区别?。。。。

数组
Loop times:21ms
Loop times:60ms


尴尬了。。。先留个疑惑,吧。

posted @ 2023-05-05 20:24  aaacarrot  阅读(99)  评论(0编辑  收藏  举报