cache技术综述
- cache电路
- cache模型
- cache算法
- 与cache相关的系统调用
0 cache简介
高速缓存(cache)是CPU内部用来加快数据访问的缓存技术。高速缓存属于SRAM,主存储器属于DRAM,一般而言主存储器一般称内存,后续我们使用内存称呼主存储器。
对于计算机程序而言,cache的存在是透明的,其含义就是在程序中可能找不到与cache相关的代码,但是对于带有cache的CPU,几乎在访问内存的数据时都用到了cache。
1 cache模型
在计算机存储层次结构中,一般将内存分成好几个层次,计算机多处用到“缓存”的思想,不仅仅cache是内存的缓存,此外内存可以视为磁盘的缓存,磁盘可以视为远程网络资源的缓存,其详细内存层次模型如下:
- 寄存器
- L1 icache和L1 dcache(数据cache和指令cache)
- L2 cache
- L3 cache
- 主存储器
- 磁盘
- 远程网络资源
其中CPU访问其中的数据速率逐渐下降,可以从下图看出CPU对cache和内存的访问时钟周期,对于CPU内部的寄存器,一般用于存储程序中局部变量,其访问时间大概为一个时钟周期,可想而知对于一个时钟为4GHz的CPU其一个时钟周期有多块。此外,下图没有说明磁盘的访问时间,一般而言,CPU访问磁盘的时间大约在秒级左右。
此图来源于https://cenalulu.github.io/images/linux/cache_line/latency.png
目前,大多数处理器包括三级cache(L1-3),例如intel core-i7有四个核,其中四个核共享一个L3 cache,L1 cache和L2 cache是每个核私有的,因此对于intel core-i7来说:
- 一个L3 cache
- 四个L2cache
- 四个L1 icache
- 四个L1 dcache
为了验证以上结论,使用cpu-z对一台Intel core i7进行测试,其结果如下:
从图中可以看出,core i7第七代有6MBytes的L3 cache一个、256KBytes的L2 cache四个等等。将其画成框图如下,其中只画出了其中一个核的关系图,紫色部分为一个核。
本文在对cache相关技术进行研究时,采用一级cache进行说明,上图只是更好的说明cache完备的模型。
1.1 情景分析
上一节重点介绍cache在电路上与CPU、主存以及总线、I/O设备之间的物理关系,本小节将重点放在从代码级上思考cache对程序的影响。
首先考虑一个程序存在时间和空间上的局部特性,具有良好局部特性的程序能大大提高执行效率,例如体现在执行完成的时间上。其局部特性与cache有重要的关系。在探讨普通应用程序与cache的关联之前,我们必须了解什么是程序的"局部性原理"
程序运行有以下3个特点:
- 时间局部性:如果一个数据/指令正在被访问,那么在近期它很可能还会被再次访问
- 空间局部性:在最近的将来将用到的信息很可能与正在使用的信息在空间地址上是临近的
- 顺序局部性:在典型程序中,除转移类指令外,大部分指令是顺序进行的
考虑这么一段程序:
#include <stdio.h>
int main(int argc,char *argv[])
{
/* 对array[][]二维数组进行按“行”赋值操作 */
int array[10][10]={0};
int i=0,j=0;
for(i=0;i<10;i++){
for(j=0;j<10;j++){
array[i][j] = 1;
}
}
retuen 0;
}
对于C语言来说,从内存角度,对一个数组存储的时,一般按照“行”对array中的数据进行存储,简而言之,**属于同一行的元素之间在内存中的地址是相邻的,上一行的最后一个元素与下一行的第一个元素是邻接的,**因此,在对array进行访问时,按照“行”对于上面这段程序具有良好的空间局部特性。
在CPU要对内存进行数据访问时,需要查看访问的数据是否在cache中:
- 如果在,称为命中,
- 如果不在,称为缺失
以下图作为研究对象。