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