cache缓存与伪共享

一、cache缓存

cache与主存之间是以块为单位读写的,这样设计是为了符合程序运行的局部性原理--时间局部性原理与空间局部性原理(参见《计算机组成原理》)

二维数组行遍历比列遍历要快,是由于二维数组是按行存储的,cache从主存中读入块,会将同行相邻元素一起写入cache,导致行遍历cache命中率大于列遍历cache命中率。

public class CacheTest {

    static final int LINE_NUM = 1024;
    static final int COLUMN_NUM = 1024;

    public static void main(String[] args){
        long [][] array = new long[LINE_NUM][COLUMN_NUM];
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < LINE_NUM; i++){//行遍历
            for (int j = 0; j < COLUMN_NUM; j++){
                array[i][j] = i*2 + j;
            }
        }
        long endTime = System.currentTimeMillis();
        long cacheTime = endTime - startTime;
        System.out.println("cache time :" + cacheTime);

        startTime = System.currentTimeMillis();
        for (int j = 0; j < COLUMN_NUM; j++){//列遍历
            for (int i = 0; i < LINE_NUM; i++){
                array[i][j] = i*2 + j;
            }
        }
        endTime = System.currentTimeMillis();
        System.out.println("no cache time :" + (endTime - startTime));
    }
}

二、伪共享

伪共享:当一个cache行中有多个变量,多线程不能同时修改更新这多个变量。导致多线程的串行运行

    /*
    * 解决伪共享方法一:cache行为64B,对象头8B,加上变量8B,加上填充的6个无用变量48B,达到一个cache行对应一个变量
    *
    */
    public final static class FiledLong{
        public volatile long value = 0L;
        public long p1,p2,p3,p4,p5,p6;
    }
    /*
     * 解决伪共享方法二:sun.misc.Contended注解
     *
     */
    @Contended
    public final static class FiledLong2{
        public volatile long value = 0L;
    }
posted on 2020-01-06 03:34  FFStayF  阅读(736)  评论(0编辑  收藏  举报