web-dev-qa-db-ja.com

Linuxアプリケーションプロファイリング

Linuxマシンでアプリケーションのパフォーマンスを記録する手段が必要です。 IDEはありません。

理想的には、プロセスにアタッチし、定期的なスナップショットを記録するアプリが必要です。メモリ使用量スレッド数CPU使用量

何か案は?

36
MalcomTucker

プログラムを高速化するためにやるべきことを探しているなら、 stackshots が必要です。これを行う簡単な方法は、pstackユーティリティ、またはlsstack入手できる場合。

gprofよりも上手くできます 公式のプロファイリングツールを使用する場合は、コールスタックをサンプリングするものが必要です実時間で、OprofileやRotateRight/Zoomなどのラインレベルのコストを提示します。

7
Mike Dunlavey

理想的には、プロセスにアタッチし、定期的なスナップショットを記録するアプリが必要です:メモリ使用量スレッド数CPU使用量

まあ、あなたのプロセスに関するこのタイプの情報を収集するために、実際にはLinuxのプロファイラーは必要ありません。
1)topをバッチモードで使用できます。強制終了されるか、N回の反復が行われるまで、バッチモードで実行されます。

top -b -p `pidof a.out`

または

top -b -p `pidof a.out` -n 100

そしてあなたはこれを得るでしょう:

$ top -b -p `pidof a.out`
top - 10:31:50 up 12 days, 19:08,  5 users,  load average: 0.02, 0.01, 0.02
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  16330584k total,  2335024k used, 13995560k free,   241348k buffers
Swap:  4194296k total,        0k used,  4194296k free,  1631880k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
24402 SK        20   0 98.7m 1056  860 S 43.9  0.0   0:11.87 a.out


top - 10:31:53 up 12 days, 19:08,  5 users,  load average: 0.02, 0.01, 0.02
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.9%us,  3.7%sy,  0.0%ni, 95.5%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  16330584k total,  2335148k used, 13995436k free,   241348k buffers
Swap:  4194296k total,        0k used,  4194296k free,  1631880k cached

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
24402 SK      20   0 98.7m 1072  860 S 19.0  0.0   0:12.44 a.out

2)psを使用できます(たとえば、シェルスクリプトで)

ps --format pid,pcpu,cputime,etime,size,vsz,cmd -p `pidof a.out`

Linuxマシンでアプリケーションのパフォーマンスを記録する手段が必要

これを行うには、Linuxカーネルが2.6.32より大きい場合はperfを、古い場合はOprofileを使用する必要があります。 (gporfのように)どちらのプログラムも、プログラムのインストルメントにあなたからの要求はありません。ただし、perfでグラフを正しく呼び出すには、-fno-omit-frame-pointerを使用してプログラムをビルドする必要があります。例:g++ -fno-omit-frame-pointer -O2 main.cpp

Linuxの場合perf

1)パフォーマンスデータを記録するには:

perf record -p `pidof a.out`

または10秒間記録するには:

perf record -p `pidof a.out` sleep 10

またはコールグラフで記録する()

perf record -g -p `pidof a.out` 

2)記録されたデータを分析する

perf report --stdio
perf report --stdio --sort=dso -g none
perf report --stdio -g none
perf report --stdio -g

RHEL 6.3では、/ boot/System.map-2.6.32-279.el6.x86_64を読み取ることが許可されているため、通常は--kallsyms =/boot/System.map-2.6.32-279.el6.x86_64を追加しますパフォーマンスレポート:

perf report --stdio -g --kallsyms=/boot/System.map-2.6.32-279.el6.x86_64

まず、これは perfを使用したLinuxプロファイリングに関するチュートリアル です。

Linuxカーネルが2.6.32より大きい場合はperfを、古い場合はoprofileを使用できます。どちらのプログラムも、プログラムをインストルメントするためにユーザーから要求されることはありません(gprofが要求するように)。ただし、パフォーマンスで呼び出しグラフを正しく取得するには、-fno-omit-frame-pointerを使用してプログラムを構築する必要があります。例:g++ -fno-omit-frame-pointer -O2 main.cpp。 perf topを使用して、アプリケーションの「ライブ」分析を確認できます。

Sudo perf top -p `pidof a.out` -K

または、実行中のアプリケーションのパフォーマンスデータを記録し、その後分析することもできます。1)パフォーマンスデータを記録するには:

perf record -p `pidof a.out`

または10秒間記録するには:

perf record -p `pidof a.out` sleep 10

またはコールグラフで記録する()

perf record -g -p `pidof a.out` 

2)記録されたデータを分析する

perf report --stdio
perf report --stdio --sort=dso -g none
perf report --stdio -g none
perf report --stdio -g

または、アプリケーションのパフォーマンスデータを記録し、この方法でアプリケーションを起動して終了するのを待つだけで、それらを分析できます。

perf record ./a.out

これは、テストプログラムのプロファイリングの例です。テストプログラムは、ファイルmain.cppにあります(main.cppをメッセージの下部に配置します)。次のようにコンパイルします。

g++ -m64 -fno-omit-frame-pointer -g main.cpp -L.  -ltcmalloc_minimal -o my_test

Libmalloc_minimial.soは-fno-omit-frame-pointerでコンパイルされているので、libc mallocはこのオプションなしでコンパイルされているようです。次に、テストプログラムを実行します

./my_test 100000000 

次に、実行中のプロセスのパフォーマンスデータを記録します。

perf record -g  -p `pidof my_test` -o ./my_test.perf.data sleep 30

次に、モジュールごとの負荷を分析します。

perf report --stdio -g none --sort comm,dso -i ./my_test.perf.data

# Overhead  Command                 Shared Object
# ........  .......  ............................
#
    70.06%  my_test  my_test
    28.33%  my_test  libtcmalloc_minimal.so.0.1.0
     1.61%  my_test  [kernel.kallsyms]

次に、関数ごとの負荷が分析されます。

perf report --stdio -g none -i ./my_test.perf.data | c++filt

# Overhead  Command                 Shared Object                       Symbol
# ........  .......  ............................  ...........................
#
    29.30%  my_test  my_test                       [.] f2(long)
    29.14%  my_test  my_test                       [.] f1(long)
    15.17%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator new(unsigned long)
    13.16%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator delete(void*)
     9.44%  my_test  my_test                       [.] process_request(long)
     1.01%  my_test  my_test                       [.] operator delete(void*)@plt
     0.97%  my_test  my_test                       [.] operator new(unsigned long)@plt
     0.20%  my_test  my_test                       [.] main
     0.19%  my_test  [kernel.kallsyms]             [k] apic_timer_interrupt
     0.16%  my_test  [kernel.kallsyms]             [k] _spin_lock
     0.13%  my_test  [kernel.kallsyms]             [k] native_write_msr_safe

     and so on ...

次に、呼び出しチェーンが分析されます。

perf report --stdio -g graph -i ./my_test.perf.data | c++filt

# Overhead  Command                 Shared Object                       Symbol
# ........  .......  ............................  ...........................
#
    29.30%  my_test  my_test                       [.] f2(long)
            |
            --- f2(long)
               |
                --29.01%-- process_request(long)
                          main
                          __libc_start_main

    29.14%  my_test  my_test                       [.] f1(long)
            |
            --- f1(long)
               |
               |--15.05%-- process_request(long)
               |          main
               |          __libc_start_main
               |
                --13.79%-- f2(long)
                          process_request(long)
                          main
                          __libc_start_main

    15.17%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator new(unsigned long)
            |
            --- operator new(unsigned long)
               |
               |--11.44%-- f1(long)
               |          |
               |          |--5.75%-- process_request(long)
               |          |          main
               |          |          __libc_start_main
               |          |
               |           --5.69%-- f2(long)
               |                     process_request(long)
               |                     main
               |                     __libc_start_main
               |
                --3.01%-- process_request(long)
                          main
                          __libc_start_main

    13.16%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator delete(void*)
            |
            --- operator delete(void*)
               |
               |--9.13%-- f1(long)
               |          |
               |          |--4.63%-- f2(long)
               |          |          process_request(long)
               |          |          main
               |          |          __libc_start_main
               |          |
               |           --4.51%-- process_request(long)
               |                     main
               |                     __libc_start_main
               |
               |--3.05%-- process_request(long)
               |          main
               |          __libc_start_main
               |
                --0.80%-- f2(long)
                          process_request(long)
                          main
                          __libc_start_main

     9.44%  my_test  my_test                       [.] process_request(long)
            |
            --- process_request(long)
               |
                --9.39%-- main
                          __libc_start_main

     1.01%  my_test  my_test                       [.] operator delete(void*)@plt
            |
            --- operator delete(void*)@plt

     0.97%  my_test  my_test                       [.] operator new(unsigned long)@plt
            |
            --- operator new(unsigned long)@plt

     0.20%  my_test  my_test                       [.] main
     0.19%  my_test  [kernel.kallsyms]             [k] apic_timer_interrupt
     0.16%  my_test  [kernel.kallsyms]             [k] _spin_lock
     and so on ...

したがって、この時点で、プログラムが時間を費やす場所がわかります。そして、これはテスト用のmain.cppです。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

time_t f1(time_t time_value)
{
  for (int j =0; j < 10; ++j) {
    ++time_value;
    if (j%5 == 0) {
      double *p = new double;
      delete p;
    }
  }
  return time_value;
}

time_t f2(time_t time_value)
{
  for (int j =0; j < 40; ++j) {
    ++time_value;
  }
  time_value=f1(time_value);
  return time_value;
}

time_t process_request(time_t time_value)
{

  for (int j =0; j < 10; ++j) {
    int *p = new int;
    delete p;
    for (int m =0; m < 10; ++m) {
      ++time_value;
    }
  }
  for (int i =0; i < 10; ++i) {
    time_value=f1(time_value);
    time_value=f2(time_value);
  }
  return time_value;
}

int main(int argc, char* argv2[])
{
  int number_loops = argc > 1 ? atoi(argv2[1]) : 1;
  time_t time_value = time(0);
  printf("number loops %d\n", number_loops);
  printf("time_value: %d\n", time_value );

  for (int i =0; i < number_loops; ++i) {
    time_value = process_request(time_value);
  }
  printf("time_value: %ld\n", time_value );
  return 0;
}
48
user184968

Linus Torvalds自身の引用:

"Don't use gprof. You're _much_ better off using the newish Linux 'perf' tool."

以降 ...

"I can pretty much guarantee that once you start using it, you'll never use gprof or oprofile again."

参照: http://marc.info/?l=git&m=126262088816902&w=2

幸運を!

22
holygeek

valgrind を使用できます。それはあなたが後で KCacheGrind のような適切なGUIを使用して分析できるファイルにデータを記録します

使用例は次のようになります。

valgrind --tool=callgrind --dump-instr=yes --simulate-cache=yes your_program

callgrind.out.xxxというファイルが生成されます。ここで、xxxはプログラムのPIDです。

edit:gprofとは異なり、valgrindはJava 一部制限あり を含む多くの異なる言語で動作します。

3
f4.

Gprofを調べましたか?コードを計測する-pgオプションを使用してコードをコンパイルする必要があります。その後、プログラムを実行し、gprofを使用して結果を確認できます。

2

cpuprofiler.com を試すこともできます。通常はtopコマンドから取得する情報を取得し、cpuの使用状況データをWebブラウザーからリモートで表示することもできます。

1
rosewater