前回の続き。
前回は Top-Down Analysis におけるMemory Boundの考え方について整理した。特に重要だったのは、cache miss があったかではなくexecution resource が idle になったかを基準に stall を定義している点である。次は、Top-Down Analysis を実現する PMU architectureについて読み解いていく。
この章は単なる implementation detail ではない。むしろ、なぜ従来の PMU では十分ではなかったのかという問題に対する論文の回答になっている。
なぜ新しい PMU event が必要なのか
従来の PMU は大量のイベントを提供していた。例えば Intel CPU であれば、cache miss / branch miss / TLB miss / stall cycle など多数のイベントが存在する。
しかし論文では、これらは bottom-up に設計されたと指摘している。つまり、この 「miss を数えよう」「この stall を観測しよう」という形で個別に event が追加されてきた。その結果、本当に重要な bottleneckを特定することが難しくなっていた。
Top-Down Analysis が必要とするもの
Top-Down Analysis が必要としているのは、イベントの発生回数ではない。必要なのはpipeline resource accountingである。つまり「slot がどこに使われたか」を分類したい。そのためには従来のcache miss countだけでは不足している。
Top-Down Analysis 用 event
論文では Top-Down Analysis を実現するために必要な event を Table 1 で定義している。
中心となる event は次の通りである。
| Event | 意味 |
|---|---|
| TotalSlots | 利用可能な issue slot 数 |
| SlotsIssued | issue された slot 数 |
| SlotsRetired | retire された slot 数 |
| FetchBubbles | frontend が供給できなかった slot |
| RecoveryBubbles | recovery 中の空 slot |
| MemStalls.* | memory stall cycle |
| OpsExecuted | execute された uop 数 |
ここで重要なのは、miss eventではなくslot accounting eventになっている点である。
TotalSlots
Top-Down Analysis の出発点となるのがTotalSlotsである。これはissue width × cycle 数として計算される。例えば 4-wide CPU なら、1 cycle = 4 slotとなる。つまり CPU 全体の capacity を表している。
SlotsIssued と SlotsRetired
次に重要なのがSlotsIssued / SlotsRetired である。
- SlotsIssued: 実際に issue された uop 数を表す。
- SlotsRetired: 最終的に commit された uop 数を表す。
この差分が重要である。
Bad Speculation の計算
論文では Bad Speculation を次のように定義している。
つまり 実行したが retire されなかった uopと recovery 中に失われた slot の和である。
FetchBubbles
意味は、backend は ready しかし frontend が uop を供給できない。つまり Frontend Bound を直接観測している。重要なのは、frontend で何が起きたかではなくbackend が idle になったかを見ている点である。
RecoveryBubbles
RecoveryBubbles は misprediction recovery / machine clear recovery 中に失われた slot を表す。これによって branch misprediction cost / をより正確に測定できる。従来の単純な branch miss count よりも遥かに有用な情報になる。
MemStalls.* Event
Memory Bound 用には専用 event が定義されている。
| Event | 意味 |
|---|---|
| MemStalls.AnyLoad | load stall |
| MemStalls.L1miss | L1 miss stall |
| MemStalls.L2miss | L2 miss stall |
| MemStalls.L3miss | L3 miss stall |
| MemStalls.Stores | store stall |
ここで重要なのは、miss 回数ではなくstall cycleを数えている点である。例えばMemStalls.L2missは L2 miss が存在しかつ execution が stall した cycleを表す。
なぜ stall cycle を数えるのか、論文が繰り返し強調しているのは、cache miss 自体は問題ではないという点である。重要なのはその miss が execution を止めたかである。
例えば L3 miss が発生していても、independent instructionを execute できているなら、まだ bottleneck ではないしたがって Top-Down Analysis はresource stallを数える。
Backend Bound は直接測らない
論文では Backend Bound は直接 event として定義されていない。代わりに、BackendBound =1-(Retiring+ FrontendBound+ BadSpeculation)として定義される。つまり残り全部である。
なぜなら Top-Level 分類が完全 partitionになっているからである。
なぜ hardware cost が低いのか
論文では、Top-Down Analysis は low-costであることを強調している。理由は、複雑な attribution hardwareを必要としないためである。例えば IBM POWER 系 CPI stack では、retirement stage で stall attributionを行っていた。また Accurate CPI Stack 系研究では、latency tracking structureなどの複雑な機構が必要だった。それに対して Top-Down Analysis は、local pipeline signalを用いた比較的単純な event だけで構成される。
なぜ issue stage を使うのか
この章でもう一つ重要なのが、issue stage accountingである。従来の解析ではretirement stageで分類することが多かった。しかし論文では、issue stageで分類している。
理由は明確である。frontend / backend 境界が最も自然に見える位置だからである。
例えばuop が issue されなかった場合、backend が拒否したなら Backend Bound、frontend が供給できなかったなら Frontend Bound となる。