高速缓存的工作原理
Cache的基本原理
我们先来看一个简单的cache,处理器每次请求一个字,并且每个块由一个单独的字组成。下图展示了该简单cache在请求数据项(该数据项初始不在cache中)前后的状态。请求发出之前,cache中保存了最近所访问过的数据项 ${X_1},{X_2},...,{X_{n - 1}}$,而处理器请求一个不在cache中的字 ${X_{n}}$。该请求将引起一次失效,然后 ${X_{n}}$ 从存储器中取到cache中。
Cache的访问过程
CPU欲访问的信息已在Cache中的比率称为Cache的命中率。设一个程序执行期间,Cache的总命中次数为 ${N_c}$,访问主存的总次数为 ${N_m}$,则命中率 $H$ 为 $H = \frac{{{N_c}}}{{{N_c} + {N_m}}}$。
可见为提高访问效率,命中率 $H$ 越接近1越好。设 ${t_c}$ 为命中时的Cache访问时间, ${t_m}$ 为未命中时的访问时间,$1-H$ 表示未命中率,则Cache——主存系统的平均访问时间${T_a}$ 为${T_a} = H{t_c} + (1 - H){t_m}$。
Cache的性能评估
平均访存时间 (Average Memory Access Time, AMAT):$AMAT = 命中时间 + 缺失率 \times 缺失代价$
AMAT = Time for a hit + Miss rate × Miss penalty
Cache和主存的映射方式
Cache行中的信息是主存中某个块的副本,地址映射是指把主存地址空间映射到Cache地址空间,这样就可以判断该数据项是否存在于cache中,即把存放在主存中的信息按照某种规则装入Cache。
标记(tag)中包含了地址信息,这些地址信息可以用来判断 cache 中的字是否就是所请求的字。标记只需包含地址的高位,也就是没有用来检索 cache 的那些位。
有效位 (valid bit) 来标识一个 cache 项是否含有有效地址。
所以总体上Cache的地址结构大致如下:
主要有以下三种方法:
1. 直接映射
每个存储器地址映射到cache中一个确定的地址,这种方法叫直接映射(direct mapped)。直接映像方式是最简单的地址映像方式,成本低,易实现,地址变换速度快,而且不涉及其他两种映像方式中的替换算法问题。但是,这种方式不够灵活,Cache的块冲突概率最高,空间利用率最低。
直接映射的关系可以定义为:
$(主存的块地址)mod(cache中的块数)$(一般cache中的块数是2的幂)
2. 全相连映射
块可以被放置在 cache 中的任意位置。这种机制称为全相联 (fully associative),因为存储器中的块可以与 cache中的任何一项相关。全相联映像方式比较灵活,Cache的块冲突概率最低、空间利用率最高,但是地址变换速度慢,而且成本高,实现起来比较困难。
3. 组相连映射
组相联(set associative)将Cache空间分成 $Q$ 个大小相同的组,让主存中的一块直接映像装入Cache中对应组的任何一块位置上,即组间采取直接映像,而组内采取全相联映像。
每个块有 $n$ 个位置可放的组相联 cache 称为 $n$ 路组相联 cache。根据索引字段,存储器中的每个块对应到 cache 中唯一的组,并且块可以放在这个组中的任何位置上。
组相连映射的关系可以定义为:
$Cache组号 =(主存的块地址)mod(Cache中的组数)$