H10 —— CPU 里的内存控制器:IMC 的架构和它与核心的交互
金句:最好的内存控制,是让 CPU 感受不到延迟的存在。
内存控制器(IMC)的位置
内存控制器(Memory Controller)是 CPU 和 DRAM 之间的桥梁,现代 CPU 把 IMC 集成在 CPU 芯片上。
CPU 芯片架构(以 Intel Skylake 为例):
┌─────────────────────────────────────────────────┐
│ CPU Package │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Core 0 │ │ Core 1 │ │ Core 2 │ ... │
│ │ L1/L2 │ │ L1/L2 │ │ L1/L2 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ ┌────┴─────────────┴──────────────┴────┐ │
│ │ Ring Bus / Mesh Interconnect │ │
│ └────┬─────────────┬──────────────┬────┘ │
│ │ │ │ │
│ ┌────┴────┐ ┌────┴────┐ ┌─────┴─────┐ │
│ │ IMC │ │ System │ │ PCIe │ │
│ │ Channel0 │ │ Agent │ │ Controller│ │
│ │ Channel1 │ │ │ │ │ │
│ └─────────┘ └──────────┘ └───────────┘ │
└─────────────────────────────────────────────────┘
IMC(Integrated Memory Controller)的位置:
- IMC 在 CPU 芯片上(Integrated)
- 通过 Ring Bus(核心数少)或 Mesh(核心数多)和核心连接
- 直接连接到 DDR PHY(物理层),再到 DIMM 插槽
vs 早期架构(North Bridge):
- 早期 CPU 是"CPU + North Bridge + South Bridge"分离
- 内存控制器在 North Bridge 里
- CPU 和内存之间通过 FSB(Front Side Bus)通信
- 延迟高(~80ns),带宽低内存控制器的架构
IMC 的内部结构(DDR4 双通道):
┌──────────────────────────────────────────────────┐
│ Memory Controller │
│ │
│ ┌────────────┐ ┌────────────┐ │
│ │ Channel 0 │ │ Channel 1 │ │
│ │ DDR4-3200 │ │ DDR4-3200 │ │
│ │ 64-bit │ │ 64-bit │ │
│ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │
│ ┌────┴──────────────────┴────┐ │
│ │ Address Decode / Routing │ │
│ └─────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────┐ │
│ │ Read/Write Queue (Scheduler) │ │
│ │ - 命令重排(Command Reordering) │ │
│ │ - 行冲突优化(Bank Conflict) │ │
│ │ - 读优先(Read Prioritization) │ │
│ └────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────┐ │
│ │ ECC Engine(纠错) │ │
│ │ - SECDED 计算 │ │
│ │ - 地址保护 │ │
│ └────────────────────────────────────────┘ │
└──────────────────────────────────────────────────┘IMC 的核心功能:
- 地址解码:把物理地址翻译成 Channel/Rank/Bank/Row/Column
- 命令调度:重排内存访问顺序,最小化行冲突
- ECC 纠错:计算和检查 ECC(RDIMM 或 ECC UDIMM)
- 时序控制:发送 ACT/READ/WRITE/PRE/REF 命令
内存控制器的调度器(Scheduler)
内存访问的调度,是性能的关键。
调度器的优化策略:
1. 命令重排(Command Reordering):
- 尽量把同一行的访问放在一起(行命中)
- 避免行冲突(行切换)
- 把 READ 优先于 WRITE(CPU 需要数据才能继续)
2. 读优先(Read Prioritization):
- 读操作通常影响指令执行(stall)
- 写操作可以延迟(Write Buffer)
- 调度器通常优先处理 READ
3. 行冲突优化(Bank Conflict Avoidance):
- 如果两个请求访问不同行,先访问已打开的行
- 把 PRE 和 ACT 延迟到真正需要时(Lazy Precharge)
4. 刷新协调(Refresh Coordination):
- 刷新期间,IMC 会延迟非紧急请求
- 如果刷新和紧急请求冲突,IMC 可能延迟刷新(tREFI 内完成即可)
实际调度效果:
请求序列(无调度):
Request A: Row=1 → ACT → READ → PRE
Request B: Row=2 → PRE → ACT → READ → PRE
Request C: Row=1 → ACT → READ
→ 总时间:3×ACT + 3×PRE + 2×READ = ~100ns
请求序列(有调度):
Reorder: C 先(A 已经有 Row 1 打开)
Request C: Row=1(打开)→ READ(直接读)
Request A: Row=1(打开)→ READ(直接读)
Request B: Row=2 → ACT → READ → PRE
→ 总时间:2×READ + ACT + READ + PRE = ~60ns
优化效果:减少 40% 延迟IMC 和 CPU 核心的连接:Ring Bus vs Mesh
多核 CPU 的内存控制器连接方式:
Ring Bus(Intel Haswell ~ Coffee Lake,4~8 核):
┌─────────────────────────────┐
│ Core0 ─── Ring ─── Core1 │
│ │ │ │
│ Core2 ─── Ring ─── Core3 │
│ │ │ │
│ IMC ── Ring ── Cache Agent │
└─────────────────────────────┘
- 所有核心和 IMC 都在同一个环上
- 访问延迟 = 跳数 × 每跳延迟
- 最坏情况:4 核系统,Core 0 到 IMC 要跳 2 站
- 典型延迟:50~60ns(L3 miss + IMC)
Mesh(Intel Skylake,10+ 核):
┌───────┬───────┬───────┬───────┐
│ Core0 │ Core1 │ Core2 │ Core3 │
├───┬───┼───┬───┼───┬───┼───┬───┤
│IMC│ │ │ │ │ │ │ IMC│
├───┴───┼───┴───┼───┴───┼───┴───┤
│ Core4 │ Core5 │ Core6 │ Core7 │
└───────┴───────┴───────┴───────┘
- 每行/列交叉点是路由器
- 路径可以绕过拥塞点
- 延迟增长比 Ring Bus 慢(O(sqrt(n)) vs O(n))
- 典型延迟:45~55ns(取决于位置)
AMD Zen 架构的 Infinity Fabric:
- 每 4 核(CCD)一个 Fabric 节点
- 节点之间用 Infinity Fabric 互联
- 延迟取决于跨节点访问的跳数内存控制器和 NUMA
在多路服务器(2P/4P)上,每个 CPU 都有自己的 IMC:
NUMA(Non-Uniform Memory Access):
2 路服务器(2 CPUs):
CPU 0:
- 核心 0~7
- IMC → Channel 0~3(本地内存)
- 连接到 CPU 1 的 UPI 链路
CPU 1:
- 核心 8~15
- IMC → Channel 0~3(本地内存)
- 连接到 CPU 0 的 UPI 链路
访问延迟:
- CPU 0 访问本地内存:~60ns
- CPU 0 访问 CPU 1 的内存:~100ns(跨 UPI)
NUMA 感知操作系统:
- Linux 可以用 numactl 绑核和内存在同一节点
- 进程尽量访问本地内存,避免跨节点访问
# 将进程绑定到 Node 0
numactl --membind=0 --cpunodebind=0 ./my_program
这就是为什么高性能数据库需要 NUMA 优化——
把数据放在访问它的 CPU 对应的内存节点上。总结
- IMC 位置:集成在 CPU 芯片上(Intel/AMD 现代 CPU),通过 Ring Bus 或 Mesh 和核心连接
- IMC 功能:地址解码、命令调度(重排优化)、ECC 纠错、时序控制
- 调度器优化:命令重排(行命中优先)、读优先、Lazy Precharge、刷新协调
- Ring Bus:适合 4~8 核,延迟 ~50~60ns,最坏跳数 2~3
- Mesh:适合 10+ 核,延迟 ~45~55ns,路径可绕过拥塞
- NUMA:多路 CPU 每路有自己的 IMC,本地访问快,跨节点访问慢(需要 numactl 优化)
H 层总结:Hardware 层从 DIMM 结构(H01)到双通道(H02)到时序(H03)到 XMP/EXPO(H04)到 SPD/Training(H05)到 PCB 走线(H06)到功耗(H07)到 ECC(H08)到制造测试(H09)到 IMC 架构(H10)——全面覆盖了内存硬件从物理连接到 CPU 控制器交互的完整链路。
下篇预告(B01):计算机是怎么知道内存有多大、内存在哪里的?e820 内存映射表——BIOS 在开机时给操作系统的第一份”地图”。
关注公众号「AI不着急」,回复”资料”获取内存学习路线图。
评论