Systems Performance 読んでいく (6章 その3)
Systems Performance: Enterprise and Cloudを読んでいく。
前回の続き。
6章5節方法論のみ。
6.5 Methodology
この節ではCPUの分析とチューニングをするための方法論を見ていく。
トピックを以下に示す
これらをすべて行うのは現実的ではないので、筆者は
- performance monitoring
- USE method
- profiling
- micro-benchmarking
- static analysis
をこの順番で分析していくことをおすすめする。 6.6節 Analysisではこれらの戦略を適用するOSのツールを紹介する。
6.5.1 Tools Method
Tools methodは利用可能なツールを1つずつ使っていく方法である。これは単純な方法である一方で、出力が貧弱であったり、時間がかかることが問題である。
CPUに対しては以下をチェックする事が考えられる。
- uptime
- vmstat
- top/prstat
- pidstat/prstat
- perf/dtrace/stap/oprofile
- perf/cpustat
何か問題が見つかったらその点について掘り下げていく。
6.5.2 USE Method
USE methodはボトルネックとエラーを全てのコンポーネントにおいて確認する方法で、パフォーマンス調査の初期に行い、その後により詳細な他の分析をおこなっていく。
CPUに関しては以下をチェックする。
- Utilization: CPUがbusyだった(idleではない)時間
- Saturation: CPU実行を待っている実行可能なプロセスの程度
- Errors: CPUエラーの数
まず、エラーを先に調べるべきである。これはいくつかのプロセッサやOSでは収集可能なエラー(error-correcting code, ECC)として検知することが出来る。
利用率は大抵OSのツールを使って%単位で見ることが出来るだろう。CPUごと、コアごとにも見ることが出来、これらの詳細はProfilingとCycle analysisによって理解できる。 CPUを制限しているような(クラウドなど)環境では、物理的な現秋よりも早く限界に達しているかもしれない。 この場合は100%の利用率を示す前にサチュレーションを起こしているかもしれないので注意する。 サチュレーションに関するメトリクスは一般的にシステム全体に対して提供されており、この度合いでどのくらい負荷がかかりすぎているかがわかる。
6.5.3 Workload Characterization
負荷の内容を知ることは、キャパシティプランニング、ベンチマーキング、シミュレーションにとても重要である。
これによって最大の負荷の要因そのものを無くすことが出来るかもしれない。
基本的なCPU負荷の要素は以下がある。
- Load averages(utilization+saturation)
- User-time to system-time ratio
- Syscall Rate
- Voluntary context switch rate
- Interrupt rate
この目的は適用されている負荷を知ることで、実行した内容ではない。 utilization/saturationで見たような実行している負荷ではなく、リクエストされた負荷を見るにはload averageが適している。
[Advanced Workload Characterization / Checklist]
詳細な負荷の内容を知るためには他にも項目がある。 CPUの問題を全体を通して考えるための質問のリストを以下に示す。
- CPUの利用率は?(全体/CPUごと)
- CPUの負荷は並行なタスクによるもの?何スレッドある?
- どのアプリケーションやユーザがCPUをつかってる?どれくらい?
- どのカーネルスレッドがCPUを使っているか?どれくらいか?
- CPU割り込みはどれくらいか?
- CPUインターコネクトの利用率はどれくらいか?
- なぜCPUが使われているのか?(ユーザ/カーネルパスの様子は?)
- どのようなタイプのストールサイクルが発生しているか?
高いレベルでの負荷のまとめ方は2章を見るように
6.5.4 profiling
プロファイリングの理解のために俯瞰図を作る。
以下のような手順で、一定の期間ごとにCPUの状態をサンプリングすることで、プロファイリングを行う。
- プロファイリングするデータを選択する
- 一定のインターバルでサンプリングを開始する
- 対象とする現象が起こるのを待つ
- サンプリングを終了し、サンプルデータを収集する
- データを処理する
DTraceのようないくつかのプロファイラツールは、データの処理を、サンプリングと同時に行うことができる。 CPUプロファイリングによるデータは以下の項目がある。
ユーザレベルとカーネルレベルの結果と取ることで、システム全体のプロファイルを取ることができるが、それでは量が膨大になってしまう。 土地ら家のみの結果でも十分な結果を見ることができるだろう。
単純な例として、DTraceで996Hzで10秒間サンプリングした結果を以下に示す。
DTraceによってすでに上記で上げた5つのステップが完了した状態である。 関数ごとに集計され、ソートされた結果を見ることができる。
キャッシュやインターコネクト、時間ベースのインターバルではなく、イベントトリガーをベースとしたプロファイリングなどの特別なCPUリソースについては、次のcycle analysisで見ていく。
6.5.5 Cycle analysis
CPU Performance counters(CPCs)を使うことでCPUのサイクルレベルでのCPU利用率がわかるようになる。 これにより、CPUがストールしている理由がL1, L2, L3キャッシュのキャッシュミスなのか、メモリI/O7日floating-pointの操作なのか、他のアクティビティ7日がわかるようになる。 そして、この情報によって、コンパイラオプションを最適化したり、コードを改善することができる。
Cycle AnalysisはCPIの計測から始める。
CPIが高い時はストールしているサイクルがどのタイプであるかを考える。
CPIが低い時はコード中に削減できる部分がないかを探す。
ここでいうCPIが高い・低いというのは、CPIが1以下であれば低い、1以上であれば高いと考えている。
CPCによる計測結果から離れて、CPCは実行中の与えられた値によって、カーネルに割り込めることに注目する。 例えば、L2キャッシュミスが10000回あったら、カーネルのスタックトレースを取るように割り込むことができる。これは特にIDEによって使われており、同じような計測がDTraceやCPC Providerによってできる。
Cycle Analysisは応用的な計測なので、コマンドラインでやるのは数日を要する。 また、CPUベンダーのマニュアルを読むためにも時間を割くことも考慮する必要がある。
6.5.6 Performance Monitoring
パフォーマンスモニタリングあh現状の問題と普段の振る舞いを知ることができる。 CPUにおける重要なメトリクスは
- Utilization: busyの割合
- Saturation: ロードアベレージから推測される実行キューの長さか、スレッドのスケジューラレイテンシ
である。 利用率はCPUごとに取るべきであり、クラウド環境などでその利用率に制限がある場合は、その制限との比較も記憶するべきである。
6.5.7 Static Performance Tuning
静的なパフォーマンスチューニングでは、環境の設定に主眼を置く。
例えば以下の観点について考える。
- いくつのCPUが利用可能か? そもそも何コア? 何ハードウェアスレッド?
- CPUアーキテクチャは1のものか複数のものか?
- CPUキャッシュサイズはどれくらいか?それらは共有されているか?
- CPUクロックの速度は?それは動的に変わるアーキテクチャか?BIOSによって有効化されているか?
- プロセッサモデルにパフォーマンス上の既知のバグはあるか?
- BIOSにパフォーマンス上の既知のバグはあるか?
- ソフトウェアによってCPU利用率の制限がかけられていないか?
6.5.8 Priority Tuning
Unix系システムでは、nice()システムコールが提供されている。正の値は優先度が低く、府の値はsuperuser出ないと設定できず、優先度が高い。 この仕組みはCPUが忙しく、強豪がはアッセイすることでスケジューラレイテンシが大きい時に役に立つ。 モニタリングエージェントやバックアップ作業のプロセスは優先度を下げても良いだろう。 nice以上のことをしたければ、スケジューラクラスやスケジューラポリシを変えることも考えられる。例えば、LinuxとSolarisであるreal-time scheduling classにすることで、全てのプロセスに割り込むことができるようになり、スケジューラレイテンシが低下するかも知れないが、その仕組みを知らないと自身の制御もできなくなることがあり、難しい。
6.5.9 Resource Controls
OSはプロセスやプロセスグループにCPUサイクルを割り当てるよく出来た仕組みを提供している。 これはCPU利用率を制限したり、柔軟なアプローチを提供したりできる。これについては6.8章で議論する。
6.5.10 CPU Binding
CPUパフォーマンスをチューニングする別の方法として、実行するプロセスやスレッドを割り当てることができる。こうすることでキャッシュが温まったり、メモリの局所性が上がることが期待できる。 大抵は以下の2つの方法で行う。
- Process binding
- プロセスを1角CPUだけに割当、そのCPUだけで実行する
- Exclusive CPU set
- CPUをパーティショニングし、それらにプロセスを割り当てる。
Linuxでは"cpusets"として、Solarisでは"processor sets"として実装されている。これらの設定の仕方は6.8章Tuningで見ていく。
6.5.11
ベンチマークツールには様々なタイプがあるが、大抵は単純な操作を何度も繰り返すようになっている。その操作の例を以下に示す。
- CPU instructions
- 整数演算、浮動小数点の操作、メモリロードとストア、分岐や他の命令
- Memory access
- 異なるCPUキャッシュへのメモリレイテンシの調査
- Higher-level languages
- CPU命令のテストと似ているが、インタープリンタや上級言語で書かれたコードによるテスト
- Operating system operations
- システムライブラリやCPUバウンドなシステムコールによるテスト
たとえどんなベンチマークツールを使うとしても、何を対象にベンチマークを手て散るのかを明確にしなければならない。 さもないと、ベンチマークツールのバージョンの違いによる最適化の差を計測することになってしまう。詳しいベンチマークに関する話は12章で扱う。
6.5.12 Scaling
キャパ不シティプランニングを元にしたスケーリングの単純な方法を示す。
- ターゲットにするユーザの集合化アプリケーションのリクエストレートを決定する
- ユーザやリクエスト米のCPU利用率を示す。現在のシステムのためにCPU利用率をユーザ数やリクエストレートとともにモニタする。将来には、CPU利用率が計測されていることで、CPU負荷ツールがユーザをしいミュレートできる。
- CPU利用率が100%の時のユーザやリクエストを推定する。これがシステムの論理的な限界である。
より現実的な観点からCPUのスケーラビリティは強豪と一貫性のためのレイテンシによってモデル化できる。これについては2.6, 2.7節を見るように
⊂゚U┬───┬~