私は (かなり大規模な) 既存のモノスレッド C アプリケーションに取り組んでいます。このコンテキストでは、特別な関数を呼び出すたびにカウンターをインクリメントするという非常に少数の追加作業を実行するようにアプリケーションを変更しました (この関数は ~ 80.000 回呼び出されます)。アプリケーションは、64 ビットの Linux カーネル 3.2.0-31-generic を -O3 オプションで実行する Ubuntu 12.04 でコンパイルされます。
驚くべきことに、インストルメント化されたバージョンのコードはより高速に実行されており、その理由を調査しています。実行時間を測定しclock_gettime(CLOCK_PROCESS_CPUTIME_ID)
、代表的な結果を得るために、100 回の実行を超える平均実行時間の値を報告しています。さらに、外界からの干渉を避けるために、他のアプリケーションが実行されていないシステムでアプリケーションを起動することをできる限り試みました (ちなみに、CLOCK_PROCESS_CPUTIME_ID は実時間ではなくプロセス時間を返すため、他のアプリケーションは「すべき」です。理論はキャッシュにのみ影響し、プロセスの実行時間には直接影響しません)
私は「命令キャッシュ効果」を疑っていました。おそらく、少し大きい (数バイト) インストルメント化されたコードは、キャッシュ内で異なる方法でより適切に収まります。この仮説は考えられますか? valegrind --tool=cachegrind を使用していくつかのキャッシュ調査を試みましたが、残念ながら、インストルメント化されたバージョンでは (論理的なように) 初期バージョンよりも多くのキャッシュ ミスが発生しています。
このテーマに関するヒントや、インストルメント化されたコードがより高速に実行される理由を見つけるのに役立つ可能性のあるアイデアを歓迎します (一部の GCC 最適化は、あるケースでは利用でき、別のケースでは利用できません。なぜですか?, ...)