目录缓存缓存一致性协议写入缓冲区和失效队列存储转发内存重排序可见性问题基本内存屏障同步机制和内存屏障虚拟机内存屏障缓存处理现在的处理能力处理器的访问速度远高于主存。主存储器的一次读或写操作所需的时间足以让处理器执行数百条指令。为了弥补处理器和主存处理能力之间的差距,在处理器和主存之间引入了A缓存。高速缓存是一种存储单元,其读取速度比主存快得多,但容量却比主存小得多。每个处理器都有自己的高速缓存。在缓存中,相当于为访问程序的每个变量存储了一份副本。变量名相当于内存地址,变量值相当于存储在相应内存空间的数据,但缓存并不总是包含所有变量的副本。缓存相当于硬件实现的哈希表(拉链法),它的键(key)是一个内存地址,它的值(value)是数据的副本或要写入内存的数据。Cache缓存的结构大致如下:缓存是一个经典的zipper哈希表结构,缓存包含若干个桶,每个桶包含若干个缓存项(很多地方也叫缓存行),一个缓存项可以分为:TagData-Block和Flag三部分,Tag用来区分数据在哪个数据条目上,Flag用来标识这个数据条目的状态。Data-Block也叫数据线,用来存放从主存读取的数据、要取出的数据或者要写入主存的数据,一条数据线可能包含几个变量的值。当处理器准备好读取一段数据时,处理器会“解码”对应的内存地址,得到三个值:index-用于确定桶号tag-用于确定缓存条目offset-用于确定偏移量在数据所在的表项中,如果根据内存地址在缓存中找到数据,则称为缓存命中,否则处理器会去主存中查找这个数据。现在处理器一般都有多级缓存,对应一级缓存(L1Cache)、二级缓存(L2Cache)、三级缓存(L3Cache)等,一般一个L1缓存会集成在处理器内核中,所以它的访问速度非常高。一般来说,缓存读取会在2-4个处理器时钟周期内完成,其中一部分用于存储指令(L1i),一部分用于存储数据(L1d)。一般来说,越靠近处理器核心的缓存,访问速率越高,制造成本越高,容量也越小。在Linux系统中,可以使用lscpu命令查看缓存层次结构。cacheentry是block读取的,也就是cpu访问的时候Whenacertaindataisselected,itisassumedthatthedatanearthedatawillbeaccessedinthefuture.所以第一次访问这个区域的时候,数据会和附近区域的数据一起读入cacheline(一般是64字节)有的时候会遇到一道面试题,遍历一个二维数组,是不是更快地水平或垂直遍历如下:arr[m][n]for(i=0;i
