命中
1.1 cpu缓存
在现代计算机当中,CPU是大脑,最终都是由它来执行所有的运算。而内存(RAM)则是血液,存放着运行的数据;但是,由于CPU和内存之间的工作频率不同,CPU如果直接去访问内存的话,系统性能将会受到很大的影响,所以在CPU和内存之间加入了三级缓存,分别是L1、L2、L3。
当CPU执行运算时,它首先会去L1缓存中查找数据,找到则返回;如果L1中不存在,则去L2中查找,找到即返回;如果L2中不存在,则去L3中查找,查到即返回。如果三级缓存中都不存在,最终会去内存中查找。对于CPU来说,走得越远,就越消耗时间,拖累性能。
在三级缓存中,越靠近CPU的缓存,速度越快,容量也越小,所以L1缓存是最快的,当然制作的成本也是最高的,其次是L2、L3。
CPU频率,就是CPU运算时的工作的频率(1秒内发生的同步脉冲数)的简称,单位是Hz。主频由过去MHZ发展到了当前的GHZ(1GHZ=103MHZ=106KHZ= 10^9HZ)。
内存频率和CPU频率一样,习惯上被用来表示内存的速度,内存频率是以MHz(兆赫)为单位来计量的。目前较为主流的内存频率1066MHz、1333MHz、1600MHz的DDR3内存,2133MHz、2400MHz、2666MHz、2800MHz、3000MHz、3200MHz的DDR4内存。
可以看得出,如果CPU直接访问内存,是一件相当耗时的操作。
1.2 缓存行
当数据被加载到三级缓存中,它是以缓存行的形式存在的,不是一个单独的项,也不是单独的指针。
在CPU缓存中,数据是以缓存行(cache line)为单位进行存储的,每个缓存行的大小一般为32--256个字节,常用CPU中缓存行的大小是64字节;CPU每次从内存中读取数据的时候,会将相邻的数据也一并读取到缓存中,填充整个缓存行;
可想而知,当我们遍历数组的时候,CPU遍历第一个元素时,与之相邻的元素也会被加载到了缓存中,对于后续的遍历来说,CPU在缓存中找到了对应的数据,不需要再去内存中查找,效率得到了巨大的提升;
但是,在多线程环境中,也会出现伪共享的情况,造成程序性能的降低,堪称无形的性能杀手;
/** * @描述 64位机,一个对象大头16 个字节,一个 long 类型 8个字节 6*8 +16 = 64个字节 占满一个缓存 * @参数 $ CPU缓存中,数据是以缓存行(cache line)为单位进行存储 * @返回值 $ * @创建人 * @创建时间 $ * @修改人和其它信息 */ public class CacheTest { ///数足够大才能 体现,数据小的时候 结果相反 因为其它数据会被加载导 一级 二级 缓存,导致结果相反。 public static int length = 1024*1024; public static long [][] longs; public static void main(String []args) throws InterruptedException { //休眠3秒加载静态文件 Thread.sleep(3000); longs = new long[length][]; for (int i = 0 ; i < length ; i++){ longs[i] = new long[6]; for (int j = 0 ; j < 6 ;j++){ longs[i][j] = 1l; } } hitCache(); catchMiss(); } /** * 演示缓存命中 */ public static void hitCache(){ long start = System.nanoTime(); int sum = 0; for (int x = 0 ; x < length ; x ++){ for (int y = 0 ; y<6 ; y++ ){ sum += longs[x][y]; } } System.out.print("hitCache: "); System.out.println(System.nanoTime() - start); } /** * 缓存位未命中 */ public static void catchMiss(){ long start = System.nanoTime(); int sum = 0; for (int y = 0 ; y < 6; y++){ for (int x = 0 ; x<length ; x++){ sum += longs[x][y]; } } System.out.print("catchMiss: "); System.out.println(System.nanoTime() - start); } } 参考博客:https://www.jianshu.com/p/1309dd03f81a
相关阅读
菜单-----工具”选项-------清除上网痕迹
引言 先看下面这两个循环遍历哪个快? int[][] array = new int[64 * 1024][1024]; // 横向遍历 for(int i = 0; i < 64 * 1024
固态硬盘做系统盘和做缓存盘有什么区别,我买了一块64GB的固态硬盘,想知道是直接将系统和游戏安装在固态硬盘上效果明显,还是用固态硬
一般大型网站,它的数据并不是存在数据库里的,而是存在缓存里的,缓存是存在内存里的,这样它的访问速度就会特别快。存在数据库的,是存在
在windows系统下,有一种特殊的技术,能把对磁盘的写入操作暂时缓存起来,等到系统空闲的时候在执行相应的操作,虽然这种技术能够很好地