1

コード AMD optron 6270 マシンを実行しています。OSはCentos 6.2リリースです。私は簡単なプログラムを作成しました

#include<stdio.h>
#include<stdlib.h>
int calling (long a);
int calling1 (long a);
int calling2 (long a);
int calling3 (long a);
int calling4 (long a);
int calling5 (long a);

void main()
{
    long a,b=0;
    printf("hi");
    for (a=0; a<10000000; a++) b++;
    b =Calling(a);
    b =Calling5(a);
    b =Calling4(a);

}

int Calling(long a)
{
    long b=0;
    for (a=0; a<100; a++) b = Calling1(a);
    return 0;
}

int Calling1(long a)
{
    long b=0;

    for (a=0; a<10000000; a++) b++;
    b =Calling2(a);
    return 0;
}

int Calling2(long a)
{
    long b=0;
    for (a=0;a<10000000;a++) b++;

    b =Calling3(a);
    return 0;
}
int Calling3(long a)
{
    long b=0;
    for (a=0;a<10000000;a++) b++;
    b =Calling4(a);
    return 0;
}
int Calling4(long a)
{
    long b=0;
    for (a=0; a<10000000; a++) b++;
    return 0;
}

int Calling5(long a)
{
    long b=0;
    for (a=0; a<10000000; a++) b++;
    b=0;
    for (a=0; a<10000000; a++) b++;
    b=0;
    for (a=0 ;a<10000000; a++) b++;
    b=0;
    for (a=0; a<10000000; a++) b++;
    b=0;
    return 0;
}

gprof と Oprofile を使用してこのコードをプロファイリングします。さまざまな報告を受けました。gprof を使用して main.exe を 2 回実行するとします。gprof Flat プロファイルを使用した最初のレポート:

各サンプルは 0.01 秒としてカウントされます。

  %   cumulative   self              self     total           
 time   seconds   seconds    calls   s/call   s/call  name

 24.80      2.96     2.96      101     0.03     0.03  Calling4
 24.71      5.91     2.95      100     0.03     0.12  Calling1
 24.63      8.84     2.94      100     0.03     0.06  Calling3
 23.78     11.68     2.84      100     0.03     0.09  Calling2
  1.01     11.80     0.12        1     0.12     0.12  Calling5
  0.34     11.84     0.04                             main
  0.00     11.84     0.00        1     0.00    11.65  Calling

gprof による 2 回目のレポート

フラットプロファイル:

各サンプルは 0.01 秒としてカウントされます。

% 累積セルフ セルフ 合計
時間 秒 秒 コール s/コール s/コール名

 25.13      2.99     2.99      100     0.03     0.12  Calling1
 24.88      5.95     2.96      101     0.03     0.03  Calling4
 24.80      8.89     2.95      100     0.03     0.06  Calling3
 23.48     11.69     2.79      100     0.03     0.09  Calling2
  1.02     11.81     0.12        1     0.12     0.12  Calling5
  0.17     11.83     0.02                             main
  0.00     11.83     0.00        1     0.00    11.66  Calling

両方のレポートは異なります。main.exe を実行するたびに、さまざまなプロファイリング レポートが表示されます。Oprofile を試したところ、次のように異なる結果が得られました。

Oprofile report1 サンプル ディレクトリに /var/lib/oprofile/samples/ を使用します。警告: /no-vmlinux が見つかりませんでした。CPU: AMD64 ファミリ 15h、速度 2.2e+06 MHz (推定) ユニット マスク 0x00 (ユニット マスクなし) で CPU_CLK_UNHALTED イベント (CPU クロックが停止していない) をカウント 100000 をカウント

samples  %        image name               symbol name
92552    24.7672  main                     Calling4
91610    24.5151  main                     Calling3
91566    24.5033  main                     Calling1
91469    24.4774  main                     Calling2
3665      0.9808  main                     Calling5
1892      0.5063  no-vmlinux               /no-vmlinux
916       0.2451  main                     main
10        0.0027  libc-2.12.so             profil_counter
1        2.7e-04  ld-2.12.so               _dl_cache_libcmp
1        2.7e-04  ld-2.12.so               _dl_relocate_object
1        2.7e-04  ld-2.12.so               _dl_sysdep_start
1        2.7e-04  ld-2.12.so               strcmp
1        2.7e-04  libc-2.12.so             __libc_fini
1        2.7e-04  libc-2.12.so             _dl_addr
1        2.7e-04  libc-2.12.so             _int_malloc
1        2.7e-04  libc-2.12.so             exit

Oプロファイルレポート2

サンプル ディレクトリに /var/lib/oprofile/samples/ を使用します。警告: /no-vmlinux が見つかりませんでした。CPU: AMD64 ファミリ 15h、速度 2.2e+06 MHz (推定) ユニット マスク 0x00 (ユニット マスクなし) で CPU_CLK_UNHALTED イベント (CPU クロックが停止していない) をカウント 100000 をカウント

サンプル % 画像名 シンボル名

92254    24.7719  main                     Calling4
91482    24.5646  main                     Calling1
91480    24.5641  main                     Calling3
91340    24.5265  main                     Calling2
3658      0.9822  main                     Calling5
1270      0.3410  no-vmlinux               /no-vmlinux
916       0.2460  main                     main
6         0.0016  libc-2.12.so             profil_counter
1        2.7e-04  ld-2.12.so               _dl_lookup_symbol_x
1        2.7e-04  ld-2.12.so               _dl_setup_hash
1        2.7e-04  ld-2.12.so               _dl_sysdep_start
1        2.7e-04  ld-2.12.so               bcmp
1        2.7e-04  libc-2.12.so             __mcount_internal
1        2.7e-04  libc-2.12.so             _dl_addr
1        2.7e-04  libc-2.12.so             _int_free
1        2.7e-04  libc-2.12.so             mcount

なぜこれが起こるのか誰か教えてもらえますか?これを引き起こす可能性のある理由は何ですか? この状況を回避して、一定のプロファイリング結果を得るにはどうすればよいですか?

4

1 に答える 1

2

その後のレポートが異なることは気にしません。レポートは、プログラムの実行方法によって大幅に異なる場合があります。さらに、2 つのプロファイル間で何が起こるかについて多くを語ることは困難です。実行中の他のプロセスに応じて、システムのキャッシュと TLB の両方が最初のプロファイル時とは異なる状態になることはほぼ間違いありません。制御されたマシンの状態を確保できない限り、一貫した結果は期待できません。

各ツールからのレポートが一致しない理由を理解するのは簡単です。2 つのツールは根本的に異なります。Oprofile は、本質的に定期的に CPU に割り込むサンプリング ベースのプロファイラーです。Gprof はインストルメンテーション ベースです。プログラムにコンパイルする必要があります。これにより、gprof が使用されていない場合に実行されるバイナリとは異なるバイナリが生成されます。その結果、gprof はタイミングを過大評価します。CPU バウンド プロセスには oprofile を使用し、I/O バウンド プロセスには gprof を使用します。

于 2014-02-27T16:18:51.400 に答える