写Java也得了解CPU–CPU缓存

发表于:2015-7-29 09:22

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:macemers    来源:51Testing软件测试网采编

  以我所使用的Xeon E3 CPU和64位操作系统和64位JVM为例,如这里所说,假设编译器采用行主序存储数组。
  64位系统,Java数组对象头固定占16字节(未证实),而long类型占8个字节。所以16+8*6=64字节,刚好等于一条缓存行的长度:
  如32-36行代码所示,每次开始内循环时,从内存抓取的数据块实际上覆盖了longs[i][0]到longs[i][5]的全部数据(刚好64字节)。因此,内循环时所有的数据都在L1缓存可以命中,遍历将非常快。
  假如,将32-36行代码注释而用25-29行代码代替,那么将会造成大量的缓存失效。因为每次从内存抓取的都是同行不同列的数据块(如longs[i][0]到longs[i][5]的全部数据),但循环下一个的目标,却是同列不同行(如longs[0][0]下一个是longs[1][0],造成了longs[0][1]-longs[0][5]无法重复利用)。运行时间的差距如下图,单位是微秒(us):
  最后,我们都希望需要的数据都在L1缓存里,但事实上经常事与愿违,所以缓存失效 (Cache Miss)是常有的事,也是我们需要避免的事。
  一般来说,缓存失效有三种情况:
  1. 第一次访问数据, 在cache中根本不存在这条数据, 所以cache miss, 可以通过prefetch解决。
  2. cache冲突, 需要通过补齐来解决(伪共享的产生)。
  3. cache满, 一般情况下我们需要减少操作的数据大小, 尽量按数据的物理顺序访问数据。
22/2<12
《2023软件测试行业现状调查报告》独家发布~

精彩评论

  • BDYD
    2015-8-06 15:24:30

     **于达校区严格遵循**总部的教学体系,秉承**“教育改变生活”理念,传承**“源自北大,永不妥协的教育品质”精神,集**于达校区多年经验,为上海地区**总部唯一授权软件测试培训中心,是**多课程高质量高就业校区。
    选择上海**,教育改变生活!选择**于达校区,成就你我!

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号