飞腾CPU体系结构之高速缓存概念

1. 高速缓存的引入

        早期CPU的设计中,CPU和内存频率相当,内存访问的延迟与CPU指令的平均执行周期相当,即在内存访问延迟内CPU也执行不了很多指令。在这种情况下,CPU和内存之间不需要高速缓存。

        随着CPU的控制部件和运算部件的设计水平越来越高,包括频率和指令流水线并行程度,而内存设计技术的发展相对于CPU而言有些滞后。在这种情况下,在一个内存访问延迟,如果CPU和内存之间没有高速缓存,CPU就不得不停下来等待内存访问的完成。

        在CPU和内存之间引入高速缓存,有效地提高了在内存访问条件下的单位时间CPU的平均指令数量。因为高速缓存的设计代价比较高,所以高速缓存仅仅是内存单元的局部副本,并不是全部内存数据。既然高速缓存是内存单元的局部副本,替换更新机制(一般采用最久未使用算法)用于高速缓存能跟踪当前经常使用的内存单元。一次替换更新的高速缓存长度,也就称为"高速缓存块"。

        当CPU需要访问某个地址的内存单元时,如果该内存单元的副本已经在某个高速缓存块中,我们称这次访存为“缓存块命中”;否则就为“缓存块缺失”。如果缓存块命中,此次访问就直接操作对应的高速缓存块;如果缓存块缺失,此次访问之前先要将数据从对应的内存单元传输到某个高速缓存块中,然后再操作该高速缓存块。

2. 高速缓存的类型

        在CPU流水线和内存之间的高速缓存有若干种分类方式,这里主要介绍两种分类方法。

        第一种是按照CPU的访问方式来分类,分为指令缓存、数据缓存和统一缓存。

  1.   指令缓存,仅供CPU取指令方式访问,虚拟地址由程序计数器PC决定。
  2.   数据缓存,仅供CPU读写数据方式访问,虚拟地址由读写数据的访存指令决定。
  3.   统一缓存,CPU取指令方式和读写数据方式都可以访问。

        第二种是按照高速缓存层次结构来分类,分为L1缓存、L2缓存、L3缓存等。

        L1缓存离CPU最近,CPU访问延迟最小;L2缓存离CPU稍微远些,CPU访问延迟也长些;L3缓存离CPU更远一些,CPU访问延迟也更长些。另外高速缓存层次结构还有一个特点,L1缓存是L2缓存的局部副本;L2缓存是L3缓存的局部副本。因此可以得出结论,离CPU越近的高速缓存,实现代价越高,容量一般越小,访问延迟越短。下面上一个常规图片。

        一般说来,L1缓存会区分数据缓存和指令缓存;L2/L3缓存不区分,即为统一缓存。

3. 高速缓存的属性

        高速缓存具有如下属性:

  1. 缓存块长度(略)
  2. 数据/指令属性(略)
  3. 访问延迟(略)
  4. 共享域

        前面三个属性我们已经介绍过了,这里重点介绍共享域属性。在讲共享属性之前,我们先抛出一个概念,”数据的访问者“。数据是指L1/L2/L3高速缓存和内存中的数据,数据的访问者是指可以发起数据访问操作的CPU核(上面我们总是含糊称为CPU)或某些外设。先上个图。

 在这个图中,数据的访问者有三个,其中两个CPU核,一个外设。L1缓存是CPU核独占,L2缓存是两个CPU核共享,L3缓存和内存是所有访问者共享。

        在上述结构中,从CPU核的角度来看缓存结构,我们将L2缓存称为“统一点”;将L3缓存称为“一致性点”。

        统一点,是最近具有统一属性的缓存,就是该CPU核的“统一点”;

        “一致性点”,是最近能让所有访问者看到相同数据的缓存,就是该CPU核的“一致性点”。

4. 飞腾CPU的高速缓存结构(以FT2000+/64为例)

        FT2000+/64有64个cpu核,每个核具有各自独立的32KB的L1数据缓存和32KB的L1指令缓存。其中四个核为一个核簇,每个核簇共享2MB的L2缓存。两个核簇附近有一个NUMA内存节点。全芯片划分为8个NUMA节点,每个NUMA节点内包含两个核簇。

        全芯片64核一共有32MB的L2缓存。L2缓存是统一缓存,不区分指令和数据。虽然每个核簇共享2M的L2缓存,芯片内L2缓存之间的一致性由硬件来处理。

        FT2000+/64没有L3缓存。

5. 高速缓存带来的问题

        数据一致性问题,是指访问者对相同地址进行数据访问时获得数据不一样。

        高速缓存带来两个数据一致性问题:

  1. 当某个CPU核修改一个内存单元时,操作只是发生在自己的L1数据缓存中。其他数据访问者(其他CPU核或外设)不能保证能访问到最新数据。
  2. 当外设修改内存单元时,操作只发生在L3缓存或内存中。其他数据访问者(所有CPU核)不能保证自己的L1/L2缓存数据得到更新。

6. 问题的解决

为了解决上述问题,缓存操作一般包括两类:

clean:CPU核执行该缓存指令,主要是强制硬件将数据往远离CPU的缓存或内存上更新。例如5.1中描述的问题,当某个CPU核修改一个内存单元,该内存写操作其实仅仅是操作本地L1数据缓存,此时其他CPU核和外设不能保证访问到最新数据;当执行clean到L2缓存后,共享L2的其他CPU核就可以保证访问到最新数据;当执行clean到内存后,所有数据访问者都能保证访问到最新数据。

invalidate:CPU核执行该缓存指令,主要是强制硬件靠近CPU的缓存数据失效。例如5.2中描述的问题,当外设修改一个内存单元,此时由于高速缓存的存在,所有CPU核不能保证能读取到最新值;CPU核在读取之前,先将L1/L2中的缓存数据失效,然后再读取,此时的读取就会因为“缓存块缺失”而从内存中获取,从而获得外设更新的数据。

clean and invalidate:CPU核执行该缓存指令,主要是强硬件先将数据往远离CPU的缓存或内存上更新,然后再将靠近CPU的缓存数据失效。这其实是clean和invalidate操作相结合。

猜你喜欢

转载自blog.csdn.net/lsshao/article/details/120265555