callgrind を使用してアプリケーションのプロファイルを作成したいと考えています。さて、非常に時間がかかるため、その間、同じマシンで Web ブラウジング、コンパイル、およびその他の集中的なタスクを実行します。
プロファイリング結果に偏りがありますか? valgrind はシミュレートされた CPUを使用するため、他の外部プロセスが valgrind の実行に干渉しないはずです。私は正しいですか?
デフォルトでは、Callgrind は時間に関連するものを何も記録しないため、収集されたすべてのメトリックは (ほとんど) マシン上の他のプロセスから独立していると期待できます。Callgrindのマニュアルにあるように、
デフォルトでは、収集されたデータは、実行された命令の数、ソース行との関係、関数間の呼び出し元と呼び出し先の関係、およびそのような呼び出しの数で構成されます。
そのため、メトリクス Callgrind レポートは、プログラムが (シミュレートされた) CPU で実行している命令にのみ依存する必要があり、そのような命令にかかる時間には依存しません。実際、シミュレートされた CPU は実際の CPU とは異なる動作をする可能性があるため (特に分岐予測に関して)、Callgrind の出力は多少誤解を招く可能性があります。ICCS 2004 で発表されたCallgrind の論文も、これについて非常に明確です。
マイクロアーキテクチャの詳細なシミュレーションが必要になるため、シミュレーションでは消費されたウォールクロック時間を予測できないことに注意してください。
ただし、どのような場合でも、シミュレートされた CPU は、実際の CPU が行っていることの影響を受けません。理由は簡単です。あなたが言ったように、あなたのプログラムはあなたのマシンではまったく実行されません。代わりに、Valgrind は実行時にプログラムを動的に変換します。つまり、シミュレートされたマシン用にバイナリを「UCode」に逆アセンブルし、分析コード (インストルメンテーションと呼ばれます) を追加してから、シミュレーションを実行するバイナリ コードを生成します。分析コードの追加により、命令カウント (Callgrind 内)、メモリ チェック (Memcheck 内)、およびその他すべてのプラグインが可能になります。
ただし、そこにはひねりがあります。当然のことながら、このような動的シミュレーションでプログラムを分離して実行するには限界があります。まず、プログラムが他のプログラムと対話する可能性があります。そのために費やされた時間は (考慮されていないため) 関係ありませんが、プロセス間通信の戻りコードは、システムで他に何が起こっているかに応じて、確実に変化する可能性があります。次に、ほとんどのシステム コールは変換せずに実行する必要があり、そのリターン コードも変更される可能性があります。これにより、プログラムの実行パスが異なり、収集されるメトリックがわずかに異なります。(余談ですが、Calgrind には、syscall 中に費やされた壁時計の時間を記録するオプションが用意されています。これは、システム内で何が起こっているかによって常に影響を受けます)。これらの制限の詳細については、Nicholas Nethercote の博士論文 (「Dynamic Binary Analysis and Instrumentation」)。