cache缓存与伪共享

Posted wqff-biubiu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
    }

以上是关于cache缓存与伪共享的主要内容,如果未能解决你的问题,请参考以下文章

Yii2片段缓存详解

如何使控制台中的视图缓存片段过期?

phalcon: 缓存片段,文件缓存,memcache缓存

如何在多个 Symfony 实例之间共享应用程序缓存(共享缓存池)?

伪共享与CPU cache line

伪共享与CPU cache line