6章、 CPUについて及びCPUに関連するBCC
目次
CPU
CPUについては、詳解システムパフォーマンスで学んだことの復習になる
スレッドの状態
- On-Proc
- CPU上で実行している
- Runnable
- 実行可能だが、順番待ち
- run queueでは優先度の値によってソートされる
- Sleep
- 割り込み不可能な待機を含む別のイベントでブロックされている
スレッドの状態遷移(CPUの実行状態から遷移するトリガー)
- 自発的
- I/O、ロック、またはスリープでブロックする場合
- 非自発的
- CPU時間の超過
- 優先度の高いスレッドによる横取り
異なるCPUへのバランシング
- 別のCPUがアイドル状態で、他のCPUのrun queueにスレッドが存在し待機時間のしきい値を超えた際に移動する(これはスケジューラにより実行される)
- 待機時間が短い場合は、移行をせずにハードウェアキャッシュが存在するはずのCPUで再度実行される
CPUキャッシュ(L1, L2, L3の場合)
- L1とL2はCPUごとのコア
- L3はソケット全体で共有
CPUのパフォーマンス分析
- CPUワークロードの取得(mpstat), 全てのCPUが使用されているかどうかの確認
- ワークロードがCPUバウンドであることの確認
- CPU使用率の高いCPUの調査
- 実行キューの遅延の確認(runqlat) システムがアイドル状態にも関わらず、コンテナのCPU制限(soft/hard)によりCPUバインドになっている可能性も探れる
- プロセス、CPUのモード、CPU IDで分類する(mpstat, top)
単一のプロセス、モード、IDで高い使用率を探す
- システム時間が長い場合はプロセスまたは呼び出しのタイプごとにシステムコールをカウントし、非効率な呼び出しを探す(perf, bpfrace, sysstat)
- プロファイラによるスタックトレースのサンプリング(フレームグラフを出力して視覚化する)
- プロファイラによって原因と思われる呼び出しを見つけたらさらに引数やオブジェクトが見れるツールを使用する
- タイマーベースのプロファイラを利用する(hardirqs)
- BPF toolを使用する
- PMCを使用してCPUのサイクルあたりの命令を測定してCPUがストールした量を見る
Perf-Stat
パフォーマンス解析ツール
オプション
-e | PMUイベントの指定 |
-d | 詳細な統計の出力(詳細なイベント及びL1とLLCデータキャッシュ) |
perf list | シンボリックイベントタイプのリストが見れる |
❯ sudo perf stat -d top top - 02:02:06 up 1:24, 1 user, load average: 0.19, 0.05, 0.02 Tasks: 325 total, 1 running, 246 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.1 us, 0.2 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 8140984 total, 4596012 free, 1603428 used, 1941544 buff/cache KiB Swap: 5661692 total, 5661692 free, 0 used. 6132404 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1216 root 20 0 1101220 36564 21444 S 0.3 0.4 0:07.13 containerd 1251 root 20 0 680156 105032 52864 S 0.3 1.3 0:37.01 Xorg 3346 atrophy 20 0 3737192 258756 120200 S 0.3 3.2 2:37.25 gnome-she+ 3618 atrophy 20 0 517800 34712 28340 S 0.3 0.4 0:03.16 vmtoolsd 4034 atrophy 20 0 961456 243628 138980 S 0.3 3.0 1:01.53 chrome 6299 atrophy 20 0 795896 38688 28872 S 0.3 0.5 0:00.46 gnome-ter+ 7106 atrophy 20 0 42932 3796 3084 S 0.3 0.0 0:00.04 top 7114 root 20 0 42928 3852 3140 R 0.3 0.0 0:00.02 top 1 root 20 0 225364 9196 6736 S 0.0 0.1 0:02.07 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.01 kthreadd 3 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_gp 4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_par_gp 6 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0+ 8 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 mm_percpu+ 9 root 20 0 0 0 0 S 0.0 0.0 0:00.08 ksoftirqd+ 10 root 20 0 0 0 0 I 0.0 0.0 0:01.18 rcu_sched 11 root rt 0 0 0 0 S 0.0 0.0 0:00.01 migration+ Performance counter stats for 'top': 30.51 msec task-clock # 0.005 CPUs utilized 4 context-switches # 0.131 K/sec 0 cpu-migrations # 0.000 K/sec 314 page-faults # 0.010 M/sec <not supported> cycles <not supported> instructions <not supported> branches <not supported> branch-misses 0 L1-dcache-loads # 0.000 K/sec 0 L1-dcache-load-misses # 0.00% of all L1-dcache hits <not supported> LLC-loads <not supported> LLC-load-misses 6.329104182 seconds time elapsed 0.007734000 seconds user 0.023203000 seconds sys
用語
voluntary context switches
- 自発的なコンテキストスイッチ
involuntary context switches
- 時間切れや、優先度の高いプロセスの実行を行うために強制的に行われた非自発的なコンテキストスイッチ
Memory Management Unit(MMU)
- 仮想アドレスと物理アドレスの変換を行う
Translation Lookaside Buffer(TLB)
- 仮想アドレスから対応するフレーム番号を取得し、物理アドレスへのアクセスを高速化させるキャッシュみたいなもの
- ヒットしなかった場合はPageTable or PageMapTableを参照し、フレーム番号を取得して物理アドレスを取得する(さらにTLBを更新する)
- 仮想アドレスから対応するフレーム番号を取得し、物理アドレスへのアクセスを高速化させるキャッシュみたいなもの
runqslower
run-queue上でタスクがon-CPUになるまでの経過時間が閾値を超えた場合に出力する
デフォルトは10000マイクロ秒(10ミリ秒)
以下は別terminalでyesコマンドを実行した
❯ sudo /usr/share/bcc/tools/runqslower Tracing run queue latency higher than 10000 us TIME COMM PID LAT(us) 17:10:24 llvmpipe-2 3382 10011 17:10:32 llvmpipe-0 3383 10065 17:10:32 llvmpipe-0 3770 13693 17:10:32 yes 3384 10648
cpudist
タスクがCPU上で処理された時間のヒストグラム
4~15ミリ秒のcountがあまりにも多いと非自発なコンテキストスイッチに遭遇している可能性が高いっぽい?
オプション
-m | ミリ秒単位で出力 |
❯ sudo /usr/share/bcc/tools/cpudist -m Tracing on-CPU time... Hit Ctrl-C to end. msecs : count distribution 0 -> 1 : 555 |****************************************| 2 -> 3 : 34 |** | 4 -> 7 : 84 |****** | 8 -> 15 : 89 |****** | 16 -> 31 : 94 |****** | 32 -> 63 : 49 |*** |
offcputime
カーネルスタックトレースによるoff-CPU時間の要約
ブロックされたoff-CPUのスタックトレースとタスク名、およびそれらが実行されなかった合計時間(off-CPU time)を出力する
❯ sudo /usr/share/bcc/tools/offcputime Tracing off-CPU time (us) of all threads by user + kernel stack... Hit Ctrl-C to end. finish_task_switch schedule schedule_timeout wait_for_completion __flush_work flush_work tty_buffer_flush_work n_tty_read tty_read __vfs_read vfs_read ksys_read __x64_sys_read do_syscall_64 entry_SYSCALL_64_after_hwframe __libc_read [unknown] - gnome-terminal- (3770) 2 // マイクロ秒表示
syscount
システム全体のsyscallのカウントの要約
プロセス単位でも取得できる
また、それぞれのレイテンシーも計れる
❯ sudo /usr/share/bcc/tools/syscount -i 1 -PL Tracing syscalls, printing top 10... Ctrl+C to quit. [18:27:57] PID COMM COUNT TIME (us) 1219 containerd 192 3847155.368 3375 gnome-shell 315 1988176.025 9798 syscount 19 1002143.822 3677 vmtoolsd 49 907569.626 706 vmtoolsd 39 907278.006 3770 gnome-terminal- 71 428708.563 1243 Xorg 145 405583.505 1313 dockerd 4 958.638 7821 chrome 2 84.800 5855 chrome 18 72.275 [18:27:57] PID COMM COUNT TIME (us) 3375 gnome-shell 280 3152947.632 1243 Xorg 182 835259.443 3557 gsd-color 4 811892.451 1219 containerd 34 701318.176 3770 gnome-terminal- 112 276658.322 3244 ibus-daemon 98 208865.191 3328 ibus-engine-sim 40 207299.887 706 vmtoolsd 8 202147.340 9798 syscount 22 173864.929 5855 chrome 16 143513.600 ❯ sudo /usr/share/bcc/tools/syscount -i 1 -L Tracing syscalls, printing top 10... Ctrl+C to quit. [18:28:25] SYSCALL COUNT TIME (us) futex 253 5027964.210 poll 191 3793821.835 epoll_wait 51 1215550.905 select 6 959713.907 pselect6 27 13272.355 writev 114 2022.668 recvmsg 544 984.996 write 83 620.120 ioctl 6 321.547 read 81 141.556
softirqs
ソフトIRQ(ソフト割り込み)イベント時間を測定する
ソフト割り込みの処理に費やされた時間を要約し、合計時間もしくはヒストグラムとして出力する
❯ sudo /usr/share/bcc/tools/softirqs Tracing soft irq event time... Hit Ctrl-C to end. SOFTIRQ TOTAL_usecs net_tx 1 tasklet 6 block 7 net_rx 47 rcu 254 timer 723 sched 1148 ❯ sudo /usr/share/bcc/tools/softirqs -d Tracing soft irq event time... Hit Ctrl-C to end. softirq = sched usecs : count distribution 0 -> 1 : 3 |**** | 2 -> 3 : 3 |**** | 4 -> 7 : 6 |******** | 8 -> 15 : 8 |*********** | 16 -> 31 : 27 |****************************************| 32 -> 63 : 9 |************* |
hardirqs
ハードIRQ(ハード割り込み)イベント時間を測定する
ハード割り込みの処理に費やされた時間を要約し、合計時間もしくはヒストグラムとして出力する
❯ sudo /usr/share/bcc/tools/hardirqs 10 1 Tracing hard irq event time... Hit Ctrl-C to end. ^C HARDIRQ TOTAL_usecs ens33 9 ❯ sudo /usr/share/bcc/tools/hardirqs 10 1 -d Tracing hard irq event time... Hit Ctrl-C to end. hardirq = 'ens33' usecs : count distribution 0 -> 1 : 0 | | 2 -> 3 : 0 | | 4 -> 7 : 0 | | 8 -> 15 : 1 |****************************************|
llcstat
CPUキャッシュの参照(最終レベルキャッシュ LLC)とプロセスごとのミスとヒット率を要約する
VMだと動作しないっぽい?
Failed to attach to a hardware event. Is this a virtual machine? 動けばこんな感じで出力される PID NAME CPU REFERENCE MISS HIT% 0 swapper/15 15 3515000 640000 81.79% 238 migration/38 38 5000 0 100.00% 4512 ntpd 11 5000 0 100.00%