前章で説明した「思い込み」と、適切な動的解析ツールを用いた「客観的な観察結果」を以下のように対比してみましょう。
デッドロックが発生した時のログファイルを見ると、スレッドAのログ出力で途切れている。これはスレッドAと何らかのスレッドでデッドロックが発生しているに違いない。
デッドロック発生時にデバッガでブレークをかけると、スレッドAがミューテックスBをロックしたあと、ミューテックスCをロックしていた。一方、スレッドDは、ミューテックスCをロックしたあとミューテックスBをロックしていた。
ARM CPUは0との比較について特別な命令セットを用意している。そのため、if (a < 4)と書かずにif (a-4<0)と書くと処理速度が向上する。
パフォーマンス測定ツールを使用したところ、何度も呼び出される関数内で不用意に多重ループを使用し、また、ループ関数内で条件分岐命令を使用している箇所があり、ここが一連の処理の流れでかなりの割合を占めていることが分かった。
こうした動的解析ツールでの解析結果に基づき、以下の様に仮説と対策を検討します。
・スレッドAとスレッドDがミューテックスを持ち合いデッドロックが発生しているのではないか?2つのスレッドにおける、ミューテックスBとミューテックスCのロックの順序を統一すれば、デッドロックが解消しないだろうか?
・多重ループを展開することで処理速度は向上しないか?また、ループ内での不要な条件分岐命令を書き換えることで、分岐予測*3の失敗を減らせるのではないか?
どうですか?最初に上げた仮説よりもずっと具体的になったと思いませんか?このように動的解析ツールは、デバッグや性能改善において、より確実な根拠を持った仮説を立てるために必要なたてるための客観的な情報を提供してくれます。
次回は、とくにアドホックな取り組みの横行する性能改善についてPlan → Do → Check → Actという皆さんにもなじみ深いデミングサイクル(PDCAサイクル)を使ったアプローチを説明していきたいと思います。
*3 最近のCPUでは、あらかじめ命令を先読みして複数の命令を同時実行します(パイプライン処理)。その際、分岐命令の予測を行いながら命令の先読み、実行を行いますが、分岐予測に失敗すると、失敗した部分の命令の実行結果が無駄になってしまいます(パイプラインハザード)。タイムクリティカルな関数内で不用意に分岐命令を多用すると思わぬパフォーマンスの劣化を導くことがあります。
Copyright © ITmedia, Inc. All Rights Reserved.