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;
}
Bỏ phiếu để đóng làm đề xuất công cụ –