2010-02-09 47 views
30

Tôi cần một số phương tiện ghi lại hiệu suất của một ứng dụng trên máy Linux. Tôi sẽ không có một IDE.Hồ sơ ứng dụng Linux

Lý tưởng nhất, tôi cần một ứng dụng mà sẽ gắn vào một quá trình và đăng ảnh chụp nhanh tuần hoàn của: bộ nhớ sử dụng số bài sử dụng CPU

Bất kỳ ý tưởng?

+0

Bỏ phiếu để đóng làm đề xuất công cụ –

Trả lời

7

Nếu bạn đang tìm kiếm những việc cần làm để có thể tăng tốc chương trình, bạn cần stackshots. Cách đơn giản để thực hiện việc này là sử dụng tiện ích pstack hoặc lsstack nếu bạn có thể nhận được.

You can do better than gprof. Nếu bạn muốn sử dụng công cụ lược tả chính thức, bạn muốn thứ gì đó lấy mẫu ngăn xếp cuộc gọi trên đồng hồ treo tường và trình bày chi phí cấp dòng, chẳng hạn như Oprofile hoặc RotateRight/Zoom.

2

Bạn đã xem xét đến gprof? Bạn cần biên dịch mã bằng tùy chọn -pg, tùy chọn mã. Sau đó, bạn có thể chạy prorgam và sử dụng gprof để xem kết quả.

+0

bạn có thể sử dụng gprof với java không? – MalcomTucker

3

Bạn có thể sử dụng valgrind. Nó ghi dữ liệu trong một tập tin mà bạn có thể phân tích sau đó sử dụng một gui đúng như KCacheGrind

Một ví dụ sử dụng sẽ là:

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

nó sẽ tạo ra một tập tin gọi là callgrind.out.xxx đó xxx là pid của chương trình

chỉnh sửa: không giống như gprof valgrind hoạt động với nhiều ngôn ngữ khác nhau bao gồm java with some limitations.

40

Lý tưởng nhất, tôi cần một ứng dụng mà sẽ gắn vào một quá trình và đăng ảnh chụp nhanh tuần hoàn của: bộ nhớ số sử dụng của việc sử dụng đề CPU

Vâng, để thu thập các loại thông tin này về quá trình của bạn bạn không thực sự cần một profiler trên Linux.
1) Bạn có thể sử dụng top ở chế độ hàng loạt. Nó chạy trong chế độ hàng loạt, hoặc cho đến khi nó bị giết hoặc cho đến khi N lần lặp được thực hiện:

top -b -p `pidof a.out` 

hoặc

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

và bạn wiil được điều này:

$ 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) Bạn có thể sử dụng ps (ví dụ: trong tập lệnh shell)

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

Tôi cần một số phương tiện ghi hiệu suất của một ứng dụng trên một máy Linux

Để làm điều này bạn cần phải sử dụng perf nếu Linux Kernal của bạn là lớn hơn 2,6 .32 hoặc Oprofile nếu nó cũ hơn. Cả hai chương trình không yêu cầu từ bạn để hướng dẫn chương trình của bạn (như gporf yêu cầu). Tuy nhiên để ger gọi đồ thị một cách chính xác trong perf bạn cần phải xây dựng chương trình của bạn với -fno-omit-frame-pointer. Ví dụ: g++ -fno-omit-frame-pointer -O2 main.cpp.

Đối với Linux perf:

1) Để ghi dữ liệu hiệu suất:

perf record -p `pidof a.out` 

hoặc để ghi lại trong 10 giây:

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

hoặc để ghi lại với đồ thị cuộc gọi ()

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

2) Phân tích các dữ liệu được ghi

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

On RHEL 6.3 nó được phép đọc /boot/System.map-2.6.32-279.el6.x86_64 vì vậy tôi thường thêm --kallsyms =/boot/System.map-2.6.32-279.el6.x86_64 khi làm báo cáo perf:

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


ở đây tôi đã viết một số thông tin về việc sử dụng Linux perf:

Trước hết - đây là tutorial about Linux profiling with perf

Bạn có thể sử dụng tính năng hoàn hảo nếu hạt nhân Linux của bạn lớn hơn 2.6.32 hoặc mở nếu nó cũ hơn. Cả hai chương trình này không yêu cầu bạn phải đưa ra chương trình của bạn (như yêu cầu của gprof). Tuy nhiên để có được đồ thị cuộc gọi một cách chính xác trong perf bạn cần phải xây dựng chương trình của bạn với -fno-omit-frame-pointer. Ví dụ: g++ -fno-omit-frame-pointer -O2 main.cpp. Bạn có thể thấy "sống" phân tích các ứng dụng của bạn với perf đầu:

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

Hoặc bạn có thể ghi dữ liệu hiệu suất của một ứng dụng đang chạy và phân tích chúng sau đó: 1) Để ghi dữ liệu hiệu suất:

perf record -p `pidof a.out` 

hoặc để ghi lại trong 10 giây:

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

hoặc để ghi lại với đồ thị cuộc gọi()

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

2) Phân tích các dữ liệu được ghi

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

Hoặc bạn có thể ghi dữ liệu performace của một ứng dụng và phân tích chúng sau đó chỉ bằng cách tung ra các ứng dụng theo cách này và chờ đợi cho nó để thoát:

perf record ./a.out 

Đây là một ví dụ về profiling một chương trình thử nghiệm các chương trình thử nghiệm là trong file main.cpp (tôi sẽ đưa main.cpp ở dưới cùng của thông điệp): tôi biên dịch nó trong wa này y:

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

tôi sử dụng libmalloc_minimial.so kể từ khi nó được biên soạn với -fno-omit-frame-con trỏ trong khi malloc libc dường như được biên dịch mà không cần tùy chọn này.Sau đó, tôi chạy chương trình thử nghiệm của tôi

./my_test 100000000 

Sau đó, tôi ghi lại dữ liệu hiệu suất của một quá trình chạy:

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

Sau đó, tôi phân tích tải mỗi mô-đun:

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] 

Sau đó tải mỗi chức năng được phân tích :

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 ... 

Sau đó, chuỗi cuộc gọi được phân tích:

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 ... 

Vì vậy, tại thời điểm này, bạn biết chương trình của bạn dành thời gian ở đâu. Và đây là main.cpp cho kỳ thi này:

#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; 
} 
+0

'hồ sơ hoàn thiện -p $ (ps aux | grep '[H] elloWord' | awk '{print $ 2}')' chú ý đến dấu ngoặc vuông xung quanh chữ cái đầu tiên của ứng dụng của bạn để grep sẽ chỉ trả về pid ứng dụng và không phải là pid của chính grep – kroiz

17

Trích dẫn Linus Torvalds chính mình:

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

và sau đó ...

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

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

Tốt may mắn!

1

Bạn cũng có thể dùng thử cpuprofiler.com. Nó nhận được thông tin bạn thường nhận được từ lệnh trên cùng và dữ liệu sử dụng cpu thậm chí có thể được xem từ xa từ trình duyệt web.

Các vấn đề liên quan