1 出现的背景
因为CPU与Memory之间的速度差异逐渐拉大,因此CPU无法容忍总是等待Memory,所以在CPU与Memory之间出现了Cache。
可以预知,CPU访问Cache的速度肯定要大大地快于访问Memory的速度。
一般来说,CPU会在内部嵌入一个Cache,称作On-Chip Cache,即L1 Cache。
CPU访问L1 Cache的速度基本上与访问Register的速度相同,大约在1~2个时钟周期。
可能还会有L2, L3 Cache,它们并不存在于CPU内部,而是通过Cache Bus或者Memory Bus与CPU进行连接。
它们的访问速度会比L1 Cache慢一些,达到几个或者更多的时钟周期,但是仍快于直接访问内存。
下面列出一款Intel的处理器,可以看到其Cache的容量情况
详细参数
品牌 英特尔Intel
型号 i7 2600K
系列 酷睿i7
平台类型 intel
接口类型 LGA 1155
核心类型 Sandy Bridge
生产工艺 32NM
核心电压 1.2V
主频范围 3.0G以上
主频 3.4GHz
一级缓存 4 x 32 KB instruction caches 2 x 32 KB data caches
二级缓存 1M
三级缓存 8M
核心数量 四核
超线程技术 是
64位处理器 是
TDP 95W
包装方式 盒装
保修 三年质保
注意到,L1 Cache是与CPU的核心数目对应的,而且又分为指令缓存和数据缓存。
2. Cache的结构
如图,摘自Computer Systems: A Programmer’s Perspective
之所以这样组织缓存,是为了给内存中每一个地址都有平等的机会进入缓存,而且方便了操作系统进行缓存算法上的优化。
是为了让CPU能够通过一种简单的方式,快速地知道某个内存地址是不是存在Cache中。
b表示每个block能够容纳多少字节,比如每个block可以存放1 word, 2 word, 4 word等等,应该视处理器能够实际支持的情况为准。
知道了m, b, C,我们可以得到不同的s和e的组合:以32位、32KB缓存为例
除了上面的计算外,S和E的具体的数值分配是决定缓存分配方式至关重要的参数,大体上可以分为以下三类:
1. E = 1 “直接映射”(Direct Mapped Caches)
即每个Set中只有一个缓存行,这是最简单的场景。
Set的作用是圈定了一个范围,这个范围用于确定对于Address中的s这几个比特位相同的内存块,能够同时并存在缓存中的数目,如果超出了这个数目,那么就要根据相应的算法,将选定的缓存行遣返回Memory去。
每个Set只有一个缓存行时,选择遣返的缓存行的算法最简单直接,只能替换掉上一个存在在缓存中的缓存行。
2. E > 1, S > 1 “组相关”(Set Associative Caches)
每个Set中有多个缓存行,这是比较一般的场景。
3. S = 1 “全相关”(Full Associative Caches)
属于“组相关”的特殊场景,即只有一个组的场景。
E的选择对缓存性能的影响
当E很大时,缓存中的一个已经存在的缓存行就有更多的继续存在下去的机会,就好像公司的一个部门要裁员1人,如果这个部门只有1人,那只能裁他;如果这个部门有100人,那么他只有1%的概率会被裁掉。
但是,当E很大时,每次进行缓存命中检测时,就需要花费更多的时间去查找和匹配;而且一旦没有命中,还要花费时间去决定选择哪一个缓存行遣返回Memory。
Intel系统中,L1和L2缓存都是4路组相关设计的。
Intel手册中关于Cache部分的描述
Intel处理器使用MESI(Modified, Exclusive, Shared, Invalid)协议来维护处理器的内部缓存与其他处理器中的缓存之间的一致性。
cache line fill
如果处理器发现当前正在从内存读的operand是可以缓存的(Cacheable),它就会将整个operand所在的cache line都读到缓存中。
cache hit
如果处理器从内存中读operand时,发现它已经被缓存在cache中了,就叫缓存命中。
write hit
如果处理器在写时,发现被写的内存已经被缓存,就叫写命中。
write allocation
如果处理器在写时,被写的内存没有被缓存,就先进行一次cache line fill,再写到缓存中。
store buffer
如果处理器打算将cache中的内容回写到memory中,它先将内容写到store buffer,然后在内存总线可用的时候再将store buffer中的内容写回到memory中。
处理器的snoop(窥探)能力
处理器有窥探其他处理器对内存的访问的情况,以及其他处理器中的内部缓存的情况的能力,以保证在处理器的内部缓存之间,以及和内存之间的一致性。
比如,一个处理器A在snooping时发现另外一个处理器B正在打算对一块A已经缓存的shared state的内存区域进行写操作,处理器A就会主动把A中的缓存invalid掉,如果以后A再想读这块内存的时候,需要重新cache line fill。
通过CPUID指令可以查看Cache和TLB的详细信息情况。
1: MOV EAX, 02H
2: CPUID
执行完之后,会在EAX,EBX,ECX,EDX寄存器中以比特位的形式,编码相应的信息。