Cache 核心原理与计算
是什么
-
定义:Cache(高速缓冲存储器) 是位于 CPU 和主存之间的高速小容量存储器。主存与 Cache 均划分为大小相等的块(Block,在 Cache 中称为行/Line)。
-
大白话:Cache 就像是桌面上放的“近期常用文件夹”。把大书架(主存)上的书按“页(块)”拿几页放在桌上,下次直接拿桌上的看(命中),不用每次都跑去书架找。
核心内容
1. 主存地址的划分(按映射方式分类)
主存地址的总位数由主存空间决定(如 )。无论哪种映射,低位均为 块内地址(Offset),位数 。
| 映射方式 | 主存地址结构划分 | 关键字段含义与位数计算 |
|---|---|---|
| 直接映射 (每个主存块只能去唯一固定的 Cache 行) | [ Tag / 标记 ] + [ Cache行号 ] + [ 块内地址 ] | |
| 全相联映射 (每个主存块可以去任意 Cache 行) | [ Tag / 标记 ] + [ 块内地址 ] | (无行号/组号字段) |
| K路组相联映射 (每个主存块去固定组里的任意行) | [ Tag / 标记 ] + [ Cache组号 ] + [ 块内地址 ] |
【Tag 计算实战示例(2020统考真题)】:
主存地址 32 位,Cache 数据区容量 32KB,主存块大小 64B,采用 8 路组相联映射(指一组有8行):
块内地址位数
Cache 行数
Cache 组数
2. Cache 总容量计算公式(全条件对比)
Cache 的总容量由 数据存储容量(Data) 和 标记阵列容量(Tag Array) 两部分组成:
单行标记开销(SRAM 存储元)组成:
-
有效位(Valid):固定 (指示该行数据是否有效)。
-
脏位/修改位(Dirty):
-
写回法(Write-back):需要 (标记该行是否被修改过)。
-
全写法/直写(Write-through):需要 (数据同步写回主存,无需脏位)。
-
-
替换算法位(Replacement):
-
直接映射:(位置固定,无需替换算法)。
-
全相联 / 组相联映射:
-
FIFO(先进先出):( 为组内行数,全相联时 )。
-
LRU(近期最少使用):(如 8 路组相联占 )。
-
RAND(随机):。
-
-
3. Cache 行号/组号的定位方法
Cache 组索引(Set Index) 指的就是该主存块/主存地址被映射到的 Cache 组号(即cache索引就是cache组号)
给定一个具体的字节物理地址(如 320),求解其对应的 Cache 行号/组号:
-
第一步(求主存块号):
-
第二步(计算定位):
-
直接映射(求行号):
-
组相联映射(求组号):
-
全相联映射:无行号/组号概念,可放入任意空闲行。
-
(注:若题目明确要求“Cache 行号从 1 开始”,则结果需 )
-
【数组寻址三步法示例】:
-
步骤一:求元素的字节物理地址
-
:数组首地址(如 320)。
-
:目标元素下标(如 即 )。
-
:总列数(如 中 )。
-
:单元素大小(如 型 )。
-
计算:。
-
-
步骤二:求元素所在的主存块号
-
步骤三:求映射到的 Cache 行号
4. 命中率差异分析(数组访问模式)
在 C 语言二维数组(如 , 占 4B,按行优先存储)遍历中:
-
按行遍历(
a[i][j]):按内存连续地址顺着读,空间局部性极其优异。-
若 1 个 Cache 块能装 个元素():
-
每访问 个连续元素,仅第 1 个元素未命中,后续 个元素连续命中。
-
命中率公式:
(如 时,命中率为 )。
-
-
按列遍历(
a[j][i]):跨行跳着读,跨行访问步长 。-
抖动/乒乓效应(Thrashing):若跨行步长恰好是 Cache 总容量的整数倍,同列元素会全部映射到同一个行/组中。
-
每次访问都会强制覆盖上一行的缓存数据,导致命中率暴跌为 0%。
-
5. 题干关键词与标记开销速查
-
映射方式描述:
-
直接映射:“直接映射方式”、“主存块只能映射到固定的 Cache 行中”。
-
全相联映射:“全相联映射方式”、“可以装入任意一行”、“采用相联存储器(CAM)按内容寻址”。
-
组相联映射:“K 路组相联”、“按每 K 行分组”。
-
-
标记开销速记口诀:
-
(注:若题干说明“不考虑其他控制位”,则只算 1 bit 有效位)
6. CPU 执行时间与 Cache 缺失罚时计算
-
基础执行时间(理想无缺失):
-
缺失总罚时(Cache 缺失损失):
【2013 统考真题演练】:
-
已知:指令条数 条,,时钟周期 ,平均每条指令访存 次,缺失率 ,单次缺失损失 。
-
求解:
-
-
缺失次数
-
-
-
例题
-
题目:
主存 256MB,按字节编址,数据 Cache 共 8 行,每行 64B。数组
int a[256][256]首地址为 320。在直接映射、写回法(1 位脏位)、无替换算法条件下:-
数据 Cache 总容量是多少?
-
求
a[0][31]对应的 Cache 行号。 -
比较按行遍历与按列遍历的 Cache 命中率。
-
-
分析:
-
主存 28 位(),块内偏移 6 位(),行号 3 位(),。单行标记 。总容量 。
-
a[0][31]地址 。主存块号 。Cache 行号 。 -
每个 Cache 块装 个元素。按行遍历每 16 个元素缺失 1 次,命中率 ;按列遍历因跨行步长 (Cache 容量 的 2 倍)导致同 Cache 行频繁冲突替换,命中率为 。
-
-
答案:
-
数据 Cache 总容量为 (或 )。
-
a[0][31]对应的 Cache 行号为 6。 -
按行遍历命中率为 ,按列遍历命中率为 。
-
⚠️ 易错点
Warning
Cache 容量 vs 数据容量:题目问“Cache 总容量”必须包含标记阵列容量(Tag + 状态位),不能只算数据区大小。
== 计算陷阱==:计算机中 ,故 行,绝不是 500。
组相联映射组号计算: 路组相联中,组号位数由组数决定(),而不是直接用总行数计算。
直写法 vs 回写法修改位:直写法(Write-through)与主存时刻一致,无修改位(0 bit);回写法(Write-back)才需要 1 bit 修改位。
==漏算基础执行时间 ==:计算总执行时间切勿只算 ,必须加上指令内部执行的 。
指令数 vs 访存次数:Cache 缺失率是针对访存操作而言的,计算缺失次数必须用“”。