先铺垫几个概念,以免后面混乱:
Socket或Processor: 指一个物理CPU芯片,盒装还是散装的。上面有很多针脚,直接安装在主板上。
Core : 指在Processor里封装一个CPU核心,每个Core都是完全独立的计算单元,我们平时说的4核心CPU,指的就是Processor里面封装了4个Core。
HT超线程: 目前Intel与AMD的Processor大多支持在一个Core里并行执行两个线程,此时从操作系统看就相当于两个逻辑CPU(Logical Processor)。大多数情况下,我们程序里提到的CPU概念就是指的这个Logical Processor。
咱们先来看几个问题:
1、CPU可以直接操作内存吗?可能一大部分老铁肯定会说:肯定的啊,不能操作内存怎么读取数据呢。
其实如果我们用这聪明的大脑想一想,咱们的台式主机大家肯定都玩过。上面CPU和内存条是两个完全独立的硬件啊,而且CPU也没有任何直接插槽用于挂载内存条的。
也就是说,CPU和内存条是物理隔离的,CPU并不能直接的访问内存条,而是需要借助主板上的其他硬件间接的来实现访问。
2、CPU的运算速度和内存条的访问速度差距有多大?呵呵呵,这么说吧,就是一个鸿沟啊,CPU的运算速度与内存访问速度之间的差距是100倍。
而由于CPU与内存之间的速度差存在N个数量级的巨大鸿沟,于是CPU最亲密的小伙伴Cache 闪亮登场了。与DRAM 家族的内存(Memory)不同,Cache来自SRAM家族。
而DRAM与SRAM的最简单区别就是后者特别快,容量特别小,电路结构非常复杂,造价特别高。
而Cache与主内存之间的巨大性能差距主要还是工作原理与结构不同:
DRAM存储一位数据只需要一个电容加一个晶体管,SRAM则需要6个晶体管。
由于DRAM的数据其实是被保存在电容里的,所以每次读写过程中的充放电环节也导致了DRAM读写数据有一个延时的问题,这个延时通常为十几到几十ns。
内存可以被看作一个二维数组,每个存储单元都有其行地址和列地址。
由于SRAM的容量很小,所以存储单元的地址(行与列)比较短,可以被一次性传输到SRAM中。DRAM则需要分别传送行与列的地址。
SRAM的频率基本与CPU的频率保持一致,而DRAM的频率直到DDR4以后才开始接近CPU的频率。
3、Cache 是怎么使用的?其实Cache 是被集成到CPU内部的一个存储单元(平时也被我们称为高速缓存),由于其造价昂贵,并且存储容量远远不能满足CPU大量、高速存取的需求。
所以出于对成本的控制,在现实中往往采用金字塔形的多级Cache体系来实现最佳缓存效果。
于是出现了,一级Cache(L1 Cache)、二级Cache(L2 Cache)及三级Cache(L3 Cache)。每一级都牺牲了部分性能指标来换取更大的容量,目的也是存储更多的热点数据。
以Intel家族Intel SandyBridge架构的CPU为例:
L1 Cache容量为64KB,访问速度为1ns左右
L2Cache容量扩大4倍,达到256KB,访问速度则降低到3ns左右
L3 Cache的容量则扩大512倍,达到32MB,访问速度也下降到12ns左右(也比访问主存的105ns(40ns+65ns)快一个数量级)
L3 Cache是被一个Socket上的所有CPU Core共享的,其实最早的L3 Cache被应用在AMD发布的K6-III处理器上,当时的L3 Cache受限于制造工艺,并没有被集成到CPU内部,而是被集成在主板上,如图:
从上图我们也能看出来,CPU如果要访问内存中的数据,则需要经过L1、L2、L3三道关卡,就是这三个Cache中都没有需要的数据,才会从主内存中直接进行读取。
最后我们来看下Intel Sandy Bridge CPU的架构图:
二、多核CPU与内存共享的问题 问题: Cache一致性问题多核CPU共享内存的问题也被称为Cache一致性问题。
其实就是多个CPU核心看到的Cache数据应该是一致的,在某个数据被某个CPU写入自己的Cache(L1 Cache)以后,其他CPU都应该能看到相同的Cache数据。
如果在自己的Cache中有旧数据,则抛弃旧数据。
考虑到每个CPU都有自己内部独占的Cache,所以这个问题与分布式Cache保持同步的问题是同一类问题
目前业界公认的解决一致性问题的最佳方案就是Intel 的MESI协议了,大多数SMP架构都采用了这一方案。
解决方案:MESI不知道大家还记得Cache Line 吗,就是我们常说的高速缓存中缓存条目里面的那个缓存行。
其实仔细想想,在进行I/O操作从来不以字节为单位,而是以块为单位,有两个原因:
I/O 操作比较慢,所以读一个字节与读连续N个字节的花费时间基本相同
数据访问一般都具有空间连续的特征
所以CPU针对Memory的读写也采用了类似于I/O块的方式
实际上,CPU Cache(高速缓存)里最小的存储单元就是Cache line(缓存行),Intel CPU 的一个Cache Line存储64个字节。
每一级Cache都被划分为很多组Cache Line,典型的情况就是4条Cache Line为一组。
当Cache从Memory中加载数据时,一次加载一条Cache Line的数据