3

gprof の使い方を学んでいたところ、このコードで奇妙な結果が得られました。

int one(int a, int b)
{
    int i, r = 0;
    for (i = 0; i < 1000; i++)
    {
        r += b / (a + 1);
    }
    return r;
}

int two(int a, int b)
{
    int i, r = 0;
    for (i = 0; i < 1000; i++)
    {
        r += b / (a + 1);
    }
    return r;
}

int main()
{
    for (int i = 1; i < 50000; i++)
    {
        one(i, i * 2);
        two(i, i * 2);
    }
    return 0;
}

これはプロファイラーの出力です

  %   cumulative   self              self     total           
 time   seconds   seconds    calls  us/call  us/call  name    
 50.67      1.14     1.14    49999    22.80    22.80  two(int, int)
 49.33      2.25     1.11    49999    22.20    22.20  one(int, int)

1 つを呼び出してから 2 つを呼び出すと、結果は逆になり、2 つが 1 つよりも時間がかかります
が、どちらも同じ関数ですが、最初の呼び出しは常に 2 番目の呼び出しよりも時間がかかりません

何故ですか?

注: アセンブリ コードはまったく同じであり、コードは最適化なしでコンパイルされています。

4

3 に答える 3

1

ランタイム最適化のまぐれだと思います。1つはレジスターを使用し、もう1つはレジスターを使用しないか、そのようなマイナーなものです。

システムクロックはおそらく100nsecの精度で動作します。30nsecまたは25nsecの平均呼び出し時間は、1クロックティック未満です。クロックティックの5%の丸め誤差はかなり小さいです。どちらの時間も十分にゼロに近いです。

于 2010-06-12T16:06:52.010 に答える
1

私の推測では、これは mcount データが解釈される方法のアーティファクトです。mcount (monitor.h) の粒度は、32 ビットのロングワード (私のシステムでは 4 バイト) のオーダーです。だから、あなたはこれを期待しないでしょう: 私は正確に同じ mon.out ファイルで prof と gprof から異なるレポートを取得します。ソラリス9 -

prof 
 %Time Seconds Cumsecs  #Calls   msec/call  Name
  46.4    2.35    2.3559999998      0.0000  .div
  34.8    1.76    4.11120000025      0.0000  _mcount
  10.1    0.51    4.62       1    510.      main
   5.3    0.27    4.8929999999      0.0000  one
   3.4    0.17    5.0629999999      0.0000  two
   0.0    0.00    5.06       1      0.      _fpsetsticky
   0.0    0.00    5.06       1      0.      _exithandle
   0.0    0.00    5.06       1      0.      _profil
   0.0    0.00    5.06      20      0.0     _private_exit, _exit
   0.0    0.00    5.06       1      0.      exit
   0.0    0.00    5.06       4      0.      atexit


gprof
   %  cumulative    self              self    total
 time   seconds   seconds    calls  ms/call  ms/call name
 71.4       0.90     0.90        1   900.00   900.00  key_2_text        <cycle 3> [2]
  5.6       0.97     0.07   106889     0.00     0.00  _findbuf [9]
  4.8       1.03     0.06   209587     0.00     0.00  _findiop [11]
  4.0       1.08     0.05                            __do_global_dtors_aux [12]
  2.4       1.11     0.03                            mem_init [13]
  1.6       1.13     0.02   102678     0.00     0.00  _doprnt [3]
  1.6       1.15     0.02                            one [14]
  1.6       1.17     0.02                            two [15]
  0.8       1.18     0.01   414943     0.00     0.00  realloc   <cycle 3> [16]
  0.8       1.19     0.01   102680     0.00     0.00  _textdomain_u     <cycle 3> [21]
  0.8       1.20     0.01   102677     0.00     0.00  get_mem [17]
  0.8       1.21     0.01                            $1 [18]
  0.8       1.22     0.01                            $2 [19]
  0.8       1.23     0.01                            _alloc_profil_buf [22]
  0.8       1.24     0.01                            _mcount (675)
于 2010-06-12T19:16:37.353 に答える
0

少し遅いのは常に最初に呼び出されるものですか?もしそうなら、それはCPUキャッシュがやっていると思います。または、オペレーティング システムによる遅延ページングである可能性があります。

ところで: どの最適化フラグがコンパイルされていますか?

于 2010-06-12T16:27:10.430 に答える