cpu缓存 java_cpu缓存java性能问题初探

在内存与cpu寄存器之间,还有一块区域叫做cpu高速缓存,即我们常常说的cache。

cache分为L1、L2、L3三级缓存,速度递减,离cpu越来越远,L1、L2每个内核自己都有,L3是每个插槽上的多个内核共用一个。cpu按照值使用频道来从1、2、3缓存逐个进行检索,L1如果没有命中,就向下继续检索L2、L3直到内存。

从CPU到

大约需要的CPU周期

大约需要的时间(单位ns)

寄存器

1 cycle

L1 Cache

~3-4 cycles

~0.5-1 ns

L2 Cache

~10-20 cycles

~3-7 ns

L3 Cache

~40-45 cycles

~15 ns

跨槽传输

~20 ns

内存

~120-240 cycles

~60-120ns

在上述缓存的存取与检索读取的操作中,最基本的单位(即内核操作缓存的最基本单位)成为缓存行(cache line),一般情况下,cache line的大小为64字节。

举个例子,我们可以设想,对于顺序存储的一个数组而言,当我们从内存中读取一个数组元素进缓存的时候,要一次读取64字节,那么这样就会将我们需要读取的元素后面的若干个8字节long也一并都进了缓存,并且这是在一个操作里完成的,没有额外的花费。大大提高了性能。

但如果我们的程序故意捣乱,干扰cpu的这种优化机制呢?

http://coderplay.iteye.com/blog/1485760  中的一个示例程序,我加了点注释。 (在此谢过原作者)

public classL1CacheMiss {private static final int RUNS = 10;private static final int DIMENSION_1 = 1024 * 1024;private static final int DIMENSION_2 = 62;private static long[][] longs;public static void main(String[] args) throwsException {/*初始化一个1024*1024行、62列的二位数组(矩阵),矩阵的每个元素都是0*/Thread.sleep(10000);

longs= new long[DIMENSION_1][];for (int i = 0; i < DIMENSION_1; i++) {

longs[i]= new long[DIMENSION_2];for (int j = 0; j < DIMENSION_2; j++) {

longs[i][j]= 0L;

}

}

System.out.println("starting....");final long start =System.nanoTime();long sum = 0L;for (int r = 0; r < RUNS; r++) {/*对列遍历,然后逐个累加每列中所有行*/

//for (int j = 0; j < DIMENSION_2; j++) {//for (int i = 0; i < DIMENSION_1; i++) {//sum += longs[i][j];//}//}

/*对行遍历,然后逐个累加每行中所有列*/

for (int i = 0; i < DIMENSION_1; i++) {for (int j = 0; j < DIMENSION_2; j++) {

sum+=longs[i][j];

}

}

}

System.out.println("duration = " + (System.nanoTime() -start));

}

}

执行结果:

starting....       duration = 679,818,029          sum = 0

starting....       duration = 12,850,546,522     sum = 0

先对行遍历只用不到1秒,而先对列遍历的话要用12秒!

如果在linux环境下,可以用perf stat -e L1-dcache-load-misses java L1CacheMiss   命令来查看L1 cache的未命中次数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值