7

SQLite に触発されて、valgrind の「cachegrind」ツールを使用して、再現可能なパフォーマンス ベンチマークを行うことを検討しています。それが出力する数値は、私が見つけた他のどのタイミング方法よりもはるかに安定していますが、それでも決定論的ではありません. 例として、単純な C プログラムを次に示します。

int main() {
  volatile int x;
  while (x < 1000000) {
    x++;
  }
}

これをコンパイルして cachegrind で実行すると、次の結果が得られます。

$ gcc -O2 x.c -o x
$ valgrind --tool=cachegrind ./x
==11949== Cachegrind, a cache and branch-prediction profiler
==11949== Copyright (C) 2002-2015, and GNU GPL'd, by Nicholas Nethercote et al.
==11949== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==11949== Command: ./x
==11949==
--11949-- warning: L3 cache found, using its data for the LL simulation.
==11949==
==11949== I   refs:      11,158,333
==11949== I1  misses:         3,565
==11949== LLi misses:         2,611
==11949== I1  miss rate:       0.03%
==11949== LLi miss rate:       0.02%
==11949==
==11949== D   refs:       4,116,700  (3,552,970 rd   + 563,730 wr)
==11949== D1  misses:        21,119  (   19,041 rd   +   2,078 wr)
==11949== LLd misses:         7,487  (    6,148 rd   +   1,339 wr)
==11949== D1  miss rate:        0.5% (      0.5%     +     0.4%  )
==11949== LLd miss rate:        0.2% (      0.2%     +     0.2%  )
==11949==
==11949== LL refs:           24,684  (   22,606 rd   +   2,078 wr)
==11949== LL misses:         10,098  (    8,759 rd   +   1,339 wr)
==11949== LL miss rate:         0.1% (      0.1%     +     0.2%  )
$ valgrind --tool=cachegrind ./x
==11982== Cachegrind, a cache and branch-prediction profiler
==11982== Copyright (C) 2002-2015, and GNU GPL'd, by Nicholas Nethercote et al.
==11982== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==11982== Command: ./x
==11982==
--11982-- warning: L3 cache found, using its data for the LL simulation.
==11982==
==11982== I   refs:      11,159,225
==11982== I1  misses:         3,611
==11982== LLi misses:         2,611
==11982== I1  miss rate:       0.03%
==11982== LLi miss rate:       0.02%
==11982==
==11982== D   refs:       4,117,029  (3,553,176 rd   + 563,853 wr)
==11982== D1  misses:        21,174  (   19,090 rd   +   2,084 wr)
==11982== LLd misses:         7,496  (    6,154 rd   +   1,342 wr)
==11982== D1  miss rate:        0.5% (      0.5%     +     0.4%  )
==11982== LLd miss rate:        0.2% (      0.2%     +     0.2%  )
==11982==
==11982== LL refs:           24,785  (   22,701 rd   +   2,084 wr)
==11982== LL misses:         10,107  (    8,765 rd   +   1,342 wr)
==11982== LL miss rate:         0.1% (      0.1%     +     0.2%  )
$

この場合、「I refs」は 2 回の実行で 0.008% しか違わないのですが、なぜこれらが異なるのか疑問に思っています。より複雑なプログラム (数十ミリ秒) では、さらに異なる場合があります。実行を完全に再現可能にする方法はありますか?

4

1 に答える 1

5

gmane.comp.debugging.valgrind のトピックの最後で、Nicholas Nethercote (Valgrind 開発チームで働く Mozilla 開発者) は、Cachegrind を使用する場合、マイナーなバリエーションが一般的であると述べています (大きな問題にはつながらないと推測できます)。 .

Cachegrind のマニュアルには、このプログラムは非常に機密性が高いと記載されています。たとえば、Linux では、アドレス空間のランダム化 (セキュリティを向上させるために使用) が非決定性の原因になる可能性があります。

注目すべきもう1つのことは、結果が非​​常に敏感であることです. プロファイリングされる実行可能ファイルのサイズ、使用する共有ライブラリのサイズ、さらにはファイル名の長さを変更すると、結果が乱れる可能性があります。変動は小さいですが、プログラムがまったく変更された場合に、完全に再現可能な結果を​​期待しないでください。

最近の GNU/Linux ディストリビューションは空間のランダム化に対応しており、セキュリティ対策として、同じプログラムを同じように実行すると、共有ライブラリが異なる場所にロードされます。これも結果を乱します。

これらの要因は、結果が超正確であると信頼すべきではないことを意味しますが、有用なほど十分に近いはずです.

于 2016-05-24T19:34:58.560 に答える