3

以下は、gcc によって生成された C++ コードの perf Linux プロファイラーからの出力です。ループが i=-1 に存在するまで、i=n から下に向かうループで (a[i]+b[i])^c[i] を計算しています。これは、私のプログラムで数時間または数日間実行できる最もホットなループです。

この出力を正しく理解している場合、perf は、この関数の時間の 57% が rdx レジスタから 8 を減算するために費やされていることを示しています。3 行上の rcx レジスタから 1 を引くのに 0.99% の時間しかかかっていないことを考えると、それはありそうにないようです。私は何かが欠けているに違いないと思います。これらの数字の説明は何ですか? 前回の指示の時間がなぜか不当に引き算されていませんか?

    3.64 :          484388:       mov    0x0(%rbp,%rdx,1),%rax
    0.64 :          48438d:       add    (%rbx,%rdx,1),%rax
    0.99 :          484391:       sub    $0x1,%rcx
    3.60 :          484395:       xor    (%rdi,%rdx,1),%rax
   57.13 :          484399:       sub    $0x8,%rdx
    0.22 :          48439d:       or     %rax,%rsi
    4.23 :          4843a0:       cmp    $0xffffffffffffffff,%rcx
    0.00 :          4843a4:       jne    484388

「perf record ./myprogram」を実行してこれらの数値を取得し、次に同じディレクトリで「perf report」を実行してから、このアセンブリを参照しました。

4

1 に答える 1

2

私はperf wikiでこれを見つけました:

割り込みベースのサンプリングは、最新のプロセッサにスキッドをもたらします。つまり、各サンプルに格納された命令ポインターは、カウンターが実際にオーバーフローした場所、つまりサンプリング期間の最後にあった場所ではなく、PMU 割り込みを処理するためにプログラムが中断された場所を示します。場合によっては、その 2 点間の距離は、分岐があれば数十命令以上になることもあります。プログラムが前進できない場合、それらの 2 つの場所はまったく同じです。このため、プロファイルを解釈する際には注意が必要です。

それが説明かもしれません。残念ながら、この wiki には、これが本当に問題なのかどうかを判断する方法や、この問題を修正する方法は記載されていません。

于 2012-10-26T17:20:05.197 に答える