|
LL-rescue 解析事例のご紹介「 Linuxカーネルのパフォーマンス (性能) 解析 」
|
|
組込みLinuxのカーネル開発において、ポーティングが完了しターゲットボード上でLinuxカーネルが動き出すと、興味の対象は障害や性能 (ここでは以下「パフォーマンス」と呼 ぶことにします) へと移っていきます。障害やパフォーマンスについて、何か「気になる現象」が見られたら、どのように解析していくかが、ここでご紹介するポイントです。 ここではLiFA (Lineo Footmark Analyzer) を活用した解析事例を紹介します。 |
|
ここでは、パフォーマンス解析の実際について、イメージが湧きやすいように、「性能的に気になる現象」が解決されるまでを、具体的にみていきましょう。
他のプロセスや複数ドライブアクセス (負荷) による、パフォーマンス低下する現象の発生。1台の USB メモリやハードディスクドライブのアクセスに比べ、複数ドライブのアクセスの場合や、複数プロセスの並行稼動などによりパフォーマンス低下を感じます。
「負荷のない時 (=性能が気にならない時) 」をリファレンスとし、「負荷を加えた時 (=性能が気になるとき) 」との相対的比較を行なうアイディアを使ってみましょう。つまり「気になる現象」度合いを、「気にならなかったとき」と比較しデータで明確に示せばよいわ けです。 さて「データで明確に」どう示せばよいでしょうか。LiFAのベース、すなわちトレーサのエンジンであるカーネルトレーサ LKSTは、膨大なトレースデータが取得されます。その中から、現象の特徴を示すうえで重要な部分を、どのように抽出、あるいは可視化したらよいかが、解 析の大きな鍵となります。 そこでまず、トレースデータの種別ごとに頻度を調べ、「負荷のない時」と「負荷を加えた時」それぞれの特性の違いを比較します。大きな違いが現れた頻度に着目し、より詳細な時間分布を調べます。このようなデータ解析を繰り返し、原因を推定していきます。 つまり全体の流れとして、まず頻度分布などによる大まかな「絞り込み」と、時間分布などによる詳細解析を繰り返し、原因を推定していきます。 LiFAのプロ セス遷移 (Context Series) グラフを使って、扱う現象を一通り説明してみましょう。トレースデータとして取得されたプロセス及びスレッドの状態 (RunningやReady, Sleep等) を色分けした折れ線グラフで表示されるため、Linuxカーネル内のCPUリソースの実行状況が一目で分かります。 次の図はgrowisofsコマンドでブロックデバイスに書き込んでいる実行中のグラフです。
図 1 ブロックデバイスへの書き込み時のプロセス遷移の観察 (単独ドライブの場合) 次の図は2つのブロックデバイスへの書き込みの場合です。2つのブロックデバイスそれぞれgrowisofsコマンドを実行すると、書き込みが極端に遅くなってしまいました。
図 2 複数ドライブへの同時書き込みでアクセスが極端に遅くなったときのプロセス遷移 図 2から、問題点つまり書き込みの遅さは読み取れるでしょうか。そのために、まず正常な場合である図 1を観察することにします。図 1の(1)の丸四角で囲ったプロセス "1013" と、それが生成したと思われる "1015" (おそらくスレッド) が定期的に "Running" (青い折れ線が "Running" となります) となります。また(2)で囲った部分から、CPUのidle状態を示すプロセス "0000" とリソースを分配し実行されていることがわかります。 ところが図 2の(3)では、書き込みのプロセスである "1013" と "1071" との間で、プロセス切り替えばかり繰り返されているように見えます。図 1の(2)で見られるようなパターンは見られず、プロセス切り替えでCPU資源を使ってしまい、肝心のブロックデバイス書き込みがされていないように見え ます。 後述するとおり、この問題は、ブロックデバイスのIOスケジューラの設定を変更しLinuxカーネルを稼動することにより解 決します。図 3がその場合のグラフです。同図の(4)、(5)が各々プロセス "948", "1054" で書き込み実行している部分となり、図 1の(2)と同様な遷移のパターンになっていることが観察されます。
図 3 カーネル設定の変更 (noop -> cfq) でアクセス速度が改善されたときのプロセス遷移の観察 以下では「性能が気になる時」と「気にならない時」のデータを、具体的に解析する手順を紹介していきましょう。
さて、アプローチの実際をみていきます。 測定系は、ターゲットボード (VIA-ME6000)、ブロックデバイス (IDE-HDD, IDE-CD/DVD, USBメモリ等をターゲットボードに接続)、負荷となるシェルスクリプト (ブロックデバイスによる書き込み遅延を考慮)、ツール (LKSTおよびLiFA Ver.2.0.0) からなります。末尾に詳細を紹介します。LKSTはLinuxカーネルの内部変数をトレースするために使用します。 LKSTによって行なったデータ収集の概要は以下のとおりです。
トレースデータの種別ごとの頻度解析から、フックポイントごとの頻度分布に顕著な違いが見られることがわかってきました。図 4の横軸にはLKSTの各フックポイントを、縦軸は一定のトレース区間でのフックポイントの通過回数を示しています。LKSTのフックポイントは Linuxカーネルのいたる箇所に存在するため、この頻度分布でトレース区間におけるLinuxカーネル全体のふるまいを大まかに知ることができます。
図 4 LKSTイベントごとの頻度分布の違い 図 5の横軸はカーネルの実行時間、縦軸は write システムコール処理*6 に 掛かった時間の長さを、カーネル内のsyscallの入口と出口で計測した特性です。この特性も、リファレンスの左図 (1台のドライブの場合) に比べ、右図 (複数ドライブの場合) は大きく異なります。左の場合は全体的に縦軸の高さがほぼ安定しているのに比べ、右の場合は極端に時間が掛かる場合があります (青い丸の部分) 。
図 5 syscall writeの時間特性の違い
データ解析の結果の考察は、次の通りまとめられます。
つまり、ブロックデバイスに書き込む効率そのものの低下よりは、ブロックデバイスに書き込むスケジューリングポリシーに、最も大きな要因があるようです。 一方別の解析で、BIO処理時間を計測し、複数ドライブへのアクセス時にもBIO処理時間自体がかかることがないことが分 かっています。このことは、書き込み効率自体の低下が原因ではないことの根拠のひとつということができるでしょう。以上より原因は、無駄なプロセス切り替 えにLinuxカーネルのリソースが費やされていることに起因するものと推定されます。
ドライブのIOスケジューラ設定は、ブロックデバイスのデバイスファイルごとに変更することができます*7 。そこでIOスケジューラ設定*8 をnoopからcfqに変更して改めて測定すると、パフォーマンスが改善し、図 4、図 5の特性も1台のドライブのみアクセスする場合に近づくことが分かりました。
ここでは、具体的事例を挙げ、パフォーマンスを改善することができました。一般的には「Linuxカーネルの解析ソリューションのモデル」として、図 6のように表されます。
図 6 カーネル解析ソリューションのモデル ここに挙げた各ステップが対応する、具体的事例について、まとめておきます。
複数のUSBメモリやハードディスクドライブ等、ブロックドライブへのアクセスのパフォーマンス低下を取り上げました。
「負荷のない時」をリファレンスとし、「負荷を加えた時」との相対的比較を行なうアイディアにもとづき、「気になる現象」が どれだけ気になるのかを、データで明確に示すことにしました。膨大なLKSTのトレースデータから、種別ごとの頻度分布の比較で大まかなふるまいを、端的 な違いが現れた頻度に対しより詳細な時間分布を調べました。解析結果に基づき、原因を推定する、つまり、「絞り込み」から原因を推定し、それに基づき詳細 解析へ、と進めていきました。
ブロックデバイスのIOスケジューラ設定を変更することにより、複数台のドライブへのアクセスも1台のドライブのみアクセスする場合に近づくことが分かりました。 LKSTはデータが膨大な分、様々な角度からデータ解 析を行なうことが可能です。例えばプロファイラ的なデータ解析より細かい、特定の処理の時間分布といった解析も可能です。したがってLKSTLAのような 頻度分布や時間分布の解析も、LiFAのプロセス遷移のグラフ表示も可能なのです。
cfqスケジューラは、ブロックデバイスへの書き込みセクタが近いもの同士をかき集めておき、なるべく一度に書き込むことで、全体の効率化を図っています。一方noopスケジューラはその措置を行なわず、書き込み要求に従う動作となります。 次にIOスケジューラ変更の手順を補足します。例えば /dev/hdaに対しスケジューラをnoopからcfqに変更する場合、make menuconfigによるカーネルコンフィグレーションで変更を行なうか、または下記を実行します。
|
||||
|
||||

English
パフォーマンス解析のアウトライン
気になる現象





