Contenu connexe
Similaire à システムパフォーマンス勉強会#4 (20)
Plus de shingo suzuki (10)
システムパフォーマンス勉強会#4
- 4. ■ 基礎
まず初めに確認すること
• 機能
• アプリケーションの役割を確認する:データベースサーバ?ウェブサー
バー?
• オペレーション
• アプリケーションの処理する要求は何か
• CPU モード
• ユーザレベルかカーネルレベルか
• 構成・設定
• 設定ファイルを使うか?管理ツールを使うか?チューニング可能なパラメー
タはどう設定されているか
• 指標
• アプリケーションの指標は提供されているか
- 5. ■ 基礎
(つづき)
• ログ
• アプリケーションはどのようなログを作っているかログからどのようなパフォーマンス
指標が分かるか
• バージョン
• アプリケーションは最新のバージョンになっているか
• バグ
• パフォーマンスに関する既知のバグはあるか?
• コミュニティ
• パフォーマンスについての質問に答えてくれるコミュニティはあるか?
• 書籍
• パフォーマンスに関する書籍、ドキュメントはあるか?
• エキスパート
• 身近にパフォーマンスの相談ができるエキスパートがいるか?
- 9. ■ビッグオー記法
• アルゴリズムの複雑度を表す指標
• 「計算量のオーダー」とも呼ばれる
• O(n) なら「オーダーエヌ」とよく読まれる
• 入力データセットが増えた時のパフォーマンスをモデル化
• 読み方
• 𝑂(𝑛2
)
• O → 平均的な条件の下であることを示す
• 最悪の場合なら Ω (オメガ)など
• n → 入力サイズ
• () の中の式→ 入力サイズに対する処理時間の増え方
• 例
• O(1) … 入力サイズによらず定数時間
• O(n) … 入力サイズに比例して処理時間が増える
- 17. 並行・並列処理
• 並行≠並列
• 並行 (concurrent)
• 複数のタスクを 1 つの CPU で同時に実行する方式
• node.js でやるようなイベントベースの非同期処理もこちらに含まれる
• パフォーマンス向上は
• CPUバウンドな処理では期待できない
• I/Oバウンドなどレイテンシが高い処理の場合には期待できる
• 並列 (parallel)
• 複数のタスクを複数の CPU で同時に実行する方式
• パフォーマンス向上は大抵の場合で期待できる
• ただし以前の Amdahl の法則のようにCPUを増やした分だけ性能が上がるわけでは
ない
• 並列であっても並行でない場合もある (←個人的な意見であるが…)
• GPU の SIMT の predicate 機構
- 18. 並行・並列処理に使う同期プリミティブ
• ミューテックスロック
• ロックを持つスレッドだけがCPUを使える
• 他のスレッドはブロックされる
• Linux では実際にはアダプティブスピニングミューテックスロックとして実
装されている
• ミューテックスロックとスピンロックの中間
• Solaris由来
• スピンロック
• ロックを持つスレッドが処理を実行できる
• 他のスレッドはループしながらロックスピンを獲得しようとする
• ブロックされず CPU から排除されないため低レイテンシのアクセスができ
るがCPUリソースが無駄になる
• RWロック
• 複数の読み込みか、ひとつの書き込みだけを認める
- 19. ノンブロッキングI/O
• ブロッキング I/O では次のパフォーマンス問題がある
• 並列実行されている I/O が多数あると個々の I/O がスレッドをブロッ
クしてしまう。
• 短時間で終了する I/O を頻繁に行うと、頻繁にコンテキストスイッチ
を行うためのオーバヘッドが出てしまう
• ノンブロッキング I/O
• 現在のスレッドをブロックせずに I/O を非同期に発行
• I/Oの実行中に他の仕事が出来る
• Node.js など
- 20. プロセッサのバインド
• プロセスやスレッドを同じ CPU で実行し続けること
• 特に NUMA (Non Unified Memory Access) 環境でメリットが多い
• メモリが CPU 別に局在しているため、プロセスが移動してしまうとオーバー
ヘッドがある
• それ以外の場合でも、プロセスがCPUを移動しなければCPUのキャッ
シュが活かせるためメリットがある
• Linux では OS が効率的にスケジューリングしてくれる
• アプリケーションによっては自分自身を CPU にバインドする
• この状態でほかの CPU バインドしてしまうとパフォーマンスが下が
るので注意
- 23. コンパイル言語の最適化
• コンパイラによる最適化
• gcc の場合は全部で 180 程の最適化オプションがある
• gcc –Q –O3 –help=optimizers
• ただしなにかしらのトレードオフがある
• フレームポインタの保存を省略するとスタックトレースが見れなくなるetc
• プログラマによる最適化
• 特に低レイヤの場合は CPU の挙動を把握して書くとパフォーマンス
が向上する場合がある
• 分岐予測を意識してコードを書く etc
- 25. インタープリタ言語のパフォーマンス
• インタープリタによるパフォーマンス向上
• 新しいバージョンを使う
• Ruby 2.5 だと依然のバージョンの 3 倍早くなる予定
• そもそもパフォーマンスマターの場合には採用しない
• プログラマによる最適化
• ホットスポットでだけ C 関数 etc の呼び出しに変える
• Python ならその部分だけ Cython にしてみるetc
• numpy などはこのアプローチをとっている
• JIT が使える場合は JIT を使う
• Python → Numba というライブラリで python 関数を JIT できる
• コードの書き方によって性能が大きく変わる場合も多い
• ドキュメントやコミュニティを調べる
- 27. 仮想マシンのパフォーマンス
• VMによる最適化
• JIT コンパイル
• バイトコードを実行時 or 適当なタイミングでネイティブコードにコンパイルす
る仕組み
• 速いが、メモリが足りなくなると JIT が働かなくなり性能が落ちることも
• VMのチューニング可能なパラメータをよく調べる
• 特にメモリ周り
• プログラマによる最適化
• Erlang そもそもそんなに早くない
• スケールアウトさせたい場合には有利
• Java, JVM 系言語
• VM は複雑なので、VM付属のプロファイラetc を使用して解析する
- 28. ガベージコレクション
• ガベージコレクションとは
• メモリ管理を自動化するもの
• プログラムは非常に書きやすくなる
• デメリット
• メモリ消費量の増加
• メモリ消費量が増えて、ページングに引っかかったりする
• CPUのコスト
• GC の実行に CPU リソースが使われる
• 大量にオブジェクトを持っていると、スキャンに時間がかかることも
• レイテンシ外れ値
• GC の実行によりアプリケーションが一時停止する場合がある
• どの程度の頻度、長さかは GC の実装による
- 30. スレッド状態の分析
• どの状態で長く時間を費やしているかわかるとさらに深い調査がで
きる
• 実行中
• どのコードパスがどれくらいの時間 CPU を消費しているか調べる
• スピンロックの可能性もあるので注意
• 実行可能
• CPUリソースが足りない=>CPUの使用状況と制限があるか調べる
• スワッピング待ち
• メモリが足りていない恐れがある⇒メモリ使用状況とリソースに制限があるか調べる
• スリープ
• アプリケーションをブロックしているリソースを調べる
• ロック
• ロックを保持しているスレッドは何か、保持スレッドが長期間ロックを保持している
のはなぜかを調べる
- 31. スレッド状態の分析
• 実行時間
• top(1) の %CPU を見る
• 実行可能時間
• /proc/*/schedstat に公開されている
• スワッピング待ち時間
• カーネルの遅延アカウンティング機能で計測
• 計測にはCONFIG_TASK_DELAY_ACCT の有効化が必要
• スリープ
• pidstat –d
• ps –l の WCHAN
• iostat
• ロック時間
• トレーシングツール
• プログラミング言語付属のツール
- 32. CPUのプロファイリング
• アプリケーションが CPU リソースをどこで消費しているか?
• perf コマンドでスタックトレースのサンプリングを行い調べる
ことができる
• 詳細は次回
• perf record –a –g –F100000 <コマンド>
• -g ⇒コールスタックを記録
• -a ⇒実行コマンドだけでなくシステム全体の情報も収集
• -F100000 ⇒100, 000Hz でサンプリング
• Brendan Gregg が可視化ツールも公開している
- 36. USEメソッド
• アプリケーションによって USE(使用率、飽和、エラー)の指標
は異なる
• 例
• キューを使うアプリ
• 使用率 -> 一定期間中にビジーになっているスレッドの割合
• 飽和 -> 要求キューに入っている要求の平均的な長さ
• エラー -> リジェクトorエラーになった要求の数
• ファイルを扱うアプリ
• 使用率 -> 利用中のファイル記述子の数
• 飽和 -> ファイルディスクリプタの読み込み待ちなど
• エラー -> EFILE などのエラー
- 38. ロック分析
• ロックに関する分析は次の2つ
• 競合のチェック
• 長過ぎるロック保持のチェック
• ツールが提供されている場合はそれを使えばよい
• Go言語 => go tool pprof <target> mutex.out
• For Linux
• perf lock
• カーネルのロックのみ,
• CONFIG_LOCKDEP と CONFIG_LOCK_STAT を有効にする必要がある
• perf trace や strace で futex_lock などをしている箇所を探すなど
• スピンロックなら CPU のプロファイリングをみて検出できるかもしれない
• ちなみに
• 本では lockstat, plockstat が紹介されているが DTrace が前提
• FreeBSD や MacOS では使えるらしい