※ 以前にgithubにてまとめたものの再掲
OSレイヤ
Linuxでは、仮想メモリと物理メモリの2層のメモリ構成をしており、
通常ユーザーランドから使用されるメモリアドレスは仮想アドレス(論理アドレス/logical adress)である.
仮想メモリは実際に必要になった時のみ物理アドレスに紐づけられる、 逆に言うと使われていない時は、物理アドレスに紐づけられない. これを Demand Paging 機構と呼ぶ1.仮想メモリは ページ(page) という単位で管理される。↑において、実際に物理メモリと紐づけられた論理アドレスと物理アドレスとのマッピング表がカーネル内に存在する。これは、ページテーブルエントリ(Page Table Entry/PTE) と呼ばれる。
※PTEはメモリ上に格納される
CPUレイヤ
CPUは、メモリを参照する時に、↑の仮想アドレス(論理アドレス/logical adress)を参照しようとする
※セグメント機構が動いていない前提↑の処理がCPU内で発火すると、 Memory Managemnt Unit(MMU) と呼ばれるCPU内の物理コンポーネントが、
CPUが見ようとした物理アドレスと論理アドレスのマッピング解決を行うためにOSレイヤで解説のページテーブルエントリ(PTE)を参照する。
これを、ページテーブルウオーク(Page Table Walk) という.ページテーブルウオークにより発生するオーバーヘッドを削減するため、
CPUは一度行われたページテーブルウオークにより得られたレコードについては
MMU内の Translation Lookaside Buffer(TLB) と呼ばれるキャッシュ機構に一時的なキャッシュとして保存を行う.次回以降、CPUがメモリを参照した時に、まず最初に TLB が参照される。
以降の処理は以下に分岐する。- A:欲しいページテーブルエントリがあったTLB上にあった( TLB HIT ) → 処理終了
- B:欲しいページテーブルエントリがあったTLB上にない( TLB MISS ) → ページテーブルウオーク発生
- B-1:ページテーブルウオークの結果欲しいレコードがPTE上にあった → 結果をTLBに乗せて終わり
- B-2:ページテーブルウオークの結果欲しいレコードがPTE上にもなかった( page fault )
⇒ CPU(1)の話を背景に、仮想メモリと物理メモリの再度の紐づけを行いPTEを更新、PET更新に伴いCPU上のTLBも一度クリア
TLBミスの発生状況の確認
perf
コマンドを使用することでTLBミスの発生状況の確認ができる。
※dTLBとiTLBの違いについては、WikipediaのTLBの記事を参照2.
# perf stat -e dTLB-loads,dTLB-stores,iTLB-load-misses,iTLB-loads -I 1000 # time counts unit events 1.001978040 27,398,445 dTLB-loads 1.001978040 14,215,811 dTLB-stores 1.001978040 54,771 iTLB-load-misses # 0.06% of all iTLB cache hits 1.001978040 89,732,044 iTLB-loads
脚注
1: The Linux Kernel / 4. メモリ管理
2: Wikipedia / Translation lookaside buffer