13

valgrind を使用して単純な C プログラムのプロファイリングを試みます。

[zsun@nel6005001 ~]$ valgrind --tool=memcheck ./fl.out
==2238== Memcheck、メモリエラー検出器
==2238== Copyright (C) 2002-2009、および GNU GPL'd, by Julianスワード等。
==2238== Valgrind-3.5.0 と LibVEX を使用。著作権情報を -h で再実行
==2238== コマンド: ./fl.out
==2238==
==2238==
==2238== ヒープの概要:
==2238== 終了時に使用中: 1,168 バイト1 ブロック
==2238== 合計ヒープ使用量: 1 割り当て、0 解放、1,168 バイト割り当て
==2238==
==2238== リークの概要:
==2238== 確実に失われました: 0 ブロックで 0 バイト
==2238= = 間接的に失われた: 0 ブロックで 0 バイト
==2238== 失われた可能性: 0 ブロックで 0 バイト
==2238== まだ到達可能: 1 ブロックで 1,168 バイト
==2238== 抑制: 0 ブロックで 0 バイト
==2238== --leak-check=full で再実行し、リークしたメモリの詳細を表示
==2238==
==2238== 検出および抑制されたエラーのカウントについては、次を使用して再実行します: -v
==2238== エラーの概要: 0 コンテキストからの 0 エラー (抑制: 8 から 12)
プロファイリング タイマーの期限が切れました

私がプロファイリングしようとしているcコードは次のとおりです。

void forloop(void){
    int fac=1;
    int count=5;
    int i,k;

    for (i = 1; i <= count; i++){
        for(k=1;k<=count;k++){
            fac = fac * i;
        }
    }
}

「プロファイリング タイマーが期限切れになりました」と表示されますが、これはどういう意味ですか? この問題を解決するには?どうも!

4

3 に答える 3

23

問題は、 でコンパイルされたプログラムで valgrind を使用していることです-pg。valgrind と gprof を一緒に使用することはできません。valgrind のマニュアルでは、Linux を使用していて、valgrind の下でプログラムの実際のエミュレーションをプロファイルする必要がある場合、OProfile を使用することを提案しています。

于 2010-01-27T19:17:36.057 に答える
1

ちなみに、これは階乗計算ではありません。

時間がどこに行くのかを本当に知りたい場合は、stackshotsを試すことができます。私はあなたのコードに無限ループを配置し、そのうちの 10 個を取りました。コードは次のとおりです。

 6: void forloop(void){ 
 7:   int fac=1; 
 8:   int count=5; 
 9:   int i,k; 
10:
11:   for (i = 1; i <= count; i++){ 
12:       for(k=1;k<=count;k++){ 
13:           fac = fac * i; 
14:       } 
15:   } 
16: } 
17:
18: int main(int argc, char* argv[])
19: {
20: int i;
21: for (;;){
22:     forloop();
23: }
24: return 0;
25: }

そして、ここにスタックショットがあり、最も頻繁なものが一番上になるように並べ替えられています。

forloop() line 12
main() line 23

forloop() line 12 + 21 bytes
main() line 23

forloop() line 12 + 21 bytes
main() line 23

forloop() line 12 + 9 bytes
main() line 23

forloop() line 13 + 7 bytes
main() line 23

forloop() line 13 + 3 bytes
main() line 23

forloop() line 6 + 22 bytes
main() line 23

forloop() line 14
main() line 23

forloop() line 7
main() line 23

forloop() line 11 + 9 bytes
main() line 23

これはあなたに何を伝えますか?12 行目は約 40% の時間を消費し、13 行目は約 20% の時間を消費しています。また、23 行目でほぼ 100% の時間が消費されていることもわかります。

つまり、12 行目でループを展開すると、およそ 100/(100-40) = 100/60 = 1.67x のスピードアップ係数が得られる可能性があります。もちろん、実際に階乗を計算しようとしている場合は、内側のループを削除するなど、このコードを高速化する他の方法もあります。

プロファイリングを行うための骨の折れる簡単な方法であるため、私はこれを指摘しているだけです。

于 2010-02-03T16:02:06.553 に答える
0

そのように計算することはできません10000!bignum階乗を計算するには、何らかの実装が必要になります。これは、int「通常」4バイトの長さであるためです。これは、「通常」保持できる2^32 - 1(signed int, 2^31) -13!それ以上であることを意味します。(「通常」8バイト)を使用したとしても、unsigned longに達するまでにオーバーフローします21!

「プロファイリング タイマーが期限切れになった」という意味については、valgrind がシグナルを受信したことを意味しますSIGPROF: http://en.wikipedia.org/wiki/SIGPROF (おそらく、プログラムに時間がかかりすぎたことを意味します)。

于 2010-01-27T10:45:28.120 に答える