引子
几年前看到Dougall Johnson写的M1 Apple芯片微架构的材料,就一直想模仿,但是一直没有挤出时间来。
范围和背景
本文讲的芯片微架构主要是指流水线(pipeline),现在芯片pipeline一般会有几个stage,通常包括fetch, decode, execute和commit,如下图所示:
整个软件执行起来似乎如绿色箭头一样是顺序执行的,但其实decode和commit之间一般是乱序的。
decode后,会把指令顺序的放到reorder buffer中,告诉执行单元尽快干活,干完之后通知reorder buffer这个活干完了。之后由commit单元按照入对顺序把执行完的指令捞出来出队。
指令在执行过程中,会拆分成更小的单元macro-ops(mops decode单元)和micro-ops(uops dispatch单元),能拆分成多少个也叫width,或者说解码宽度(pipeline width)。
下图是ARM Neoverse V1的微架构,可以观察到每个单元的width,有多少个EU(执行单元)
再来一个苹果M1的对比:
本文软件探测的范围实际上就是想覆盖上图中所有的单元,包括各个Cache,ROB大小,EUs种类个数,LSU个数。
所有代码可以参考 我的工具箱。
Cache探测
Cache探测包括时延和带宽,主要通过pointer chase,这种算法已经在主流的内存测试套lmbench中实现,一般是一个数组,每个数组元素中保存一个指针,指向下一个要访问的数组元素。
通过修改步长去访问不同大小的数组,观察cache miss导致时延的变化,来判断cache大小。
更多有趣的cache影响软件行为,可以参考陈浩的这篇文章与程序员相关的CPU缓存知识
执行单元个数
主要看不同种类指令的吞吐率,可以参考uarch bench,也就是参考链接中的第一篇文章。
ROB大小
主要参考Henry Wang的测试ROB大小的文章,也放在参考链接中了。
通过填充NOP指定在两次cache miss的load中,来观察执行时间的变化,由于nop指令执行时间非常短,一旦时间变化很大,那么可以判断第二次cache miss的指令在ROB队列以外了。
参考
- Performance Speed Limits
- uarch bench wiki
- The Microarchitecture Behind Meltdown
- x86, x64 Instruction Latency, Memory Latency and CPUID dumps
- realworldtech and its forum
- uops info
- The microarchitecture of Intel, AMD and VIA CPUs: An optimization guide for assembly programmers and compiler makers
- Intel Core Microarchitecture Pipeline
- CPU Introspection: Intel Load Port Snooping
- AmpereOne at Hot Chips 2024: Maximizing Density
- computer microarchitecture之out-of-order execution
- Apple Microarchitecture Research by Dougall Johnson
- Measuring Reorder Buffer Capacity
- Memory Performance in a Nutshell
- Finding Your Memory Access Performance Bottlenecks
- computer architecture - microarchitectural channels
- performance tools
- The Validation Buffer Microarchitecture for Multithreaded Processor
- Neoverse V1 - Microarchitectures - ARM
- 移动芯片排行
- Arm’s New Cortex-A78 and Cortex-X1
- Apple M1
- ARM processor
- RPi 4 tuning: The code