Akemi

CPU缓存介绍

2025/05/21

多数系统都有两到三层缓存
多级别的CPU缓存有助于处理器提供大小和延迟的最佳配置。L1 cache的数据访问时延为1ns。较大的L2缓存的访问延迟通常是10纳秒,而主存的访问延迟大约是60纳秒。

1
2
3
4
5
lscpu
L1d cache: 32K
L1i cache: 32K
L2 cache: 1024K
L3 cache: 33792K

NUMA技术

设计原理

  • 节点构成:每个NUMA节点包含一个或多个CPU插槽及直接连接的内存模块。例如,双路服务器中,两个CPU各自配备独立的内存通道,形成两个节点。
  • 访问差异
    • 本地内存:CPU访问所属节点的内存(延迟低,约数十纳秒)。
    • 远端内存:跨节点访问其他CPU关联的内存(延迟可能增加50%以上,具体取决于互联技术)。

硬件实现

  • 物理布局
    • 主板设计需支持多处理器插槽,每个插槽集成内存控制器(如AMD的Zen架构、Intel的Xeon系列),减少对北桥芯片的依赖。
    • 示例:4路服务器主板划分4个NUMA节点,每个CPU直连4条DDR4通道,总内存带宽分散至各节点。
  • 互联技术
    • 使用高速总线(如Intel的Ultra Path Interconnect,带宽可达20GB/s以上)或片上网络(AMD的Infinity Fabric)降低节点间通信延迟。

缓存架构

在多处理器系统上,每个CPU都有自己独立的缓存。每个缓存都有一个相关联的缓存控制器。当处理器引用主存时,缓存控制器首先检查请求的地址是否在缓存中,以满足处理器的请求。这被称为缓存hit。如果请求的内存不在缓存中,那么就会发生缓存miss;请求的位置必须从主存读取,处理器将数据存储在缓存中。这被称为缓存fill

1
![](https://ws-blog-img.oss-cn-hangzhou.aliyuncs.com/wangsheng/20250521191743017.png)

写操作的情况下,缓存内存可以配置为透写(write through)或回写(write-back)。如果启用了透写缓存,那么当缓存内存的某一行被更新时,对应的位置在主存也必须更新。如果启用了回写缓存,在重新分配缓存行之前,对缓存行的写入不会被写回主存。回写缓存比透写缓存更有效。

缓存关联性

1.直接映射缓存:直接映射缓存是最便宜的缓存类型。直接映射缓存的每一行只能缓存主存中的特定位置。使用直接映射缓存,搜索时间更快,因为缓存数据映射到一个特定的内存位置,但缓存命中率较低。

2.完全关联缓存:全关联缓存是最灵活的缓存类型,因此也是最昂贵的,因为它需要最多的电路来实现。完全关联的高速缓存线路可以高速缓存主存中的任何位置。使用全关联缓存,搜索时间非常长,因为CPU在搜索主存之前必须遍历整个缓存来确定数据是否存在,但缓存命中率很高。

3.关联设置缓存:设置关联缓存内存在直接映射缓存和完全关联缓存之间提供了很好的折衷。这种高速缓存通常被称为n-way关联集,其中n是2的某个幂。Set associative cache memory允许将一个内存位置缓存在n行缓存中的任意一行中。大多数系统妥协并使用集合关联缓存存储器。

分析CPU缓存利用率

valgrind工具集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sudo yum install valgrind

程序编译时保留调试信息,以便定位代码位置
gcc -g -O0 -o my_program my_program.c

# 启动分析
valgrind --tool=cachegrind --branch-sim=yes ./my_program

--tool=cachegrind:指定使用Cachegrind工具。
--branch-sim=yes:启用分支预测分析。
--cache-sim=yes(默认启用):缓存模拟。
--I1=<size>,<assoc>,<line_size>:自定义L1指令缓存配置(如--I1=32768,8,64表示32KB,8路组相联,64B行大小)。

运行后会生成cachegrind.out.<pid>文件,使用以下工具解析
cg_annotate cachegrind.out.12345 --auto=yes

CATALOG
  1. 1. NUMA技术
    1. 1.1. 设计原理
    2. 1.2. 硬件实现
  2. 2. 缓存架构
    1. 2.1. 缓存关联性
  3. 3. 分析CPU缓存利用率