CPU全层级缓存未命中时会空闲等待内存数据还是异步执行其他指令?
CPU发生全层级缓存未命中时的运行行为
现代高性能通用CPU不会在所有层级缓存miss时直接进入空闲等待状态,会通过非阻塞缓存+乱序执行架构,在等待内存返回数据的间隙执行其他无依赖的指令;只有当没有任何可独立调度的指令时,才会触发流水线停顿。
- 非阻塞缓存是硬件基础:现代CPU的L1、L2缓存都内置了MSHR(缺失状态保持寄存器),发生缓存miss时,控制器会把本次读请求的目标地址、要写回的寄存器等信息存在MSHR条目里,直接把读请求下发到内存控制器,不会卡死整个执行流水线。只要MSHR还有空余条目,就能同时处理多个在途的缓存miss请求。
- 乱序调度负责填充等待间隙:DDR内存的访问延迟通常在100~300个CPU时钟周期,这段时间里CPU的指令调度器会从指令窗口里筛选所有和本次miss读结果没有依赖关系的指令,送到ALU、FPU等执行单元运行。只要存在足够多的独立指令,这几百个周期的间隙会被完全利用,不会有算力浪费。
- 只有两种情况会真的进入停顿等待状态:
- 指令窗口里所有待执行的指令都依赖本次miss的读取结果,没有任何可独立运行的指令
- 同时发生的缓存miss数量太多,占满了所有MSHR条目,新的内存请求没法下发
- 特殊场景说明:
早期的顺序执行微控制器、极低功耗核心确实采用阻塞式缓存设计,遇到缓存miss会直接停等直到数据返回,但这类核心不属于当前桌面、服务器、移动旗舰设备使用的主流高性能CPU范畴。如果缓存miss触发了页表缺页异常,CPU会直接切入内核态执行缺页处理逻辑,也不会原地空闲。
直观的代码示例:
int a = *uncached_addr; // 访问地址触发全层级cache miss int b = 1 + 2; int c = b * 3; int d = c + 100; int res = a + d; // 仅该指令需要等待a从内存返回上述代码运行时,b、c、d的计算会在等待a返回的周期内全部执行完成,CPU不会因为读a的miss就空等几百个周期。
内容的提问来源于stack exchange,提问作者Christian Kammerer
相关产品推荐
相关产品推荐

