V ideálním případě potřebuji aplikaci, která se připojí k procesu a zaznamenává pravidelné snímky:
- Využití paměti
- počet vláken
- Využití CPU
Abyste mohli shromažďovat tento typ informací o vašem procesu, nepotřebujete v Linuxu profiler.
-
Můžete použít
top
v dávkovém režimu. Běží v dávkovém režimu, dokud není zabit, nebo dokud není provedeno N iterací:top -b -p `pidof a.out`
nebo
top -b -p `pidof a.out` -n 100
a dostanete toto:
$ 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
-
Můžete použít
ps
(například ve skriptu shellu)
ps --format pid,pcpu,cputime,etime,size,vsz,cmd -p `pidof a.out`
Potřebuji nějaké prostředky pro záznam výkonu aplikace na počítači se systémem Linux
Chcete-li to provést, musíte použít
perf
pokud je vaše jádro Linuxu vyšší než 2.6.32 nebo OProfile, pokud je starší. Oba programy od vás nevyžadují instrumentaci vašeho programu (jako Gprof vyžaduje). Chcete-li však správně získat graf volání vperf
musíte sestavit svůj program pomocí -fno-omit-frame-pointer. Například:g++ -fno-omit-frame-pointer -O2 main.cpp
.
Jako pro Linux perf
:
-
Záznam údajů o výkonu:
perf record -p `pidof a.out`
nebo pro záznam po dobu 10 sekund:
perf record -p `pidof a.out` sleep 10
nebo pro záznam pomocí grafu hovorů ()
perf record -g -p `pidof a.out`
-
Pro analýzu zaznamenaných dat
perf report --stdio perf report --stdio --sort=dso -g none perf report --stdio -g none perf report --stdio -g
Na RHEL 6.3 je povoleno číst /boot/System.map-2.6.32-279.el6.x86_64, takže obvykle přidávám --kallsyms=/boot/System.map-2.6.32-279.el6.x86_64, když vytvoření zprávy o výkonu:
Zde jsem napsal nějaké další informace o používání Linuxu `perf`:perf report --stdio -g --kallsyms=/boot/System.map-2.6.32-279.el6.x86_64
Za prvé - toto je tutoriál o profilování Linuxu pomocí perf
Můžete použít perf pokud je vaše jádro Linuxu vyšší než 2.6.32 nebo OProfile, pokud je starší. Oba programy od vás nevyžadují instrumentaci vašeho programu (jako Gprof vyžaduje). Abychom však správně získali graf hovorů v perf potřebujete sestavit svůj program s
-fno-omit-frame-pointer
. Například:g++ -fno-omit-frame-pointer -O2 main.cpp
.Můžete vidět "živou" analýzu vaší aplikace pomocí perf top :
sudo perf top -p `pidof a.out` -K
Nebo můžete zaznamenat údaje o výkonu běžící aplikace a poté je analyzovat:
-
Záznam údajů o výkonu:
perf record -p `pidof a.out`
nebo pro záznam po dobu 10 sekund:
perf record -p `pidof a.out` sleep 10
nebo pro záznam pomocí grafu hovorů ()
perf record -g -p `pidof a.out`
-
Pro analýzu zaznamenaných dat
perf report --stdio
perf report --stdio --sort=dso -g none
perf report --stdio -g none
perf report --stdio -g
Nebo můžete zaznamenat údaje o výkonu aplikace a poté je analyzovat pouhým spuštěním aplikace tímto způsobem a čekáním na její ukončení:
perf record ./a.out
Toto je příklad profilování testovacího programu.
Testovací program je v souboru main.cpp (main.cpp je na konci odpovědi):
Zkompiluji to takto:
g++ -m64 -fno-omit-frame-pointer -g main.cpp -L. -ltcmalloc_minimal -o my_test
Používám libmalloc_minimial.so, protože je kompilován s -fno-omit-frame-pointer, zatímco libc malloc se zdá být kompilován bez této možnosti. Poté spustím svůj testovací program:
./my_test 100000000
Poté zaznamenám údaje o výkonu běžícího procesu:
perf record -g -p `pidof my_test` -o ./my_test.perf.data sleep 30
Poté analyzuji zatížení na modul:
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]
Poté se analyzuje zatížení na funkci:
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 ...
Poté jsou analyzovány řetězce volání:
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 tuto chvíli tedy víte, kde váš program tráví čas.
A toto je main.cpp soubor pro test:
#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;
}
Cituji samotného Linuse Torvaldse:
Nepoužívejte gprof. Jste moc lepší je použít nový linuxový nástroj 'perf'.
A později ...
Mohu téměř zaručit, že jakmile jej začnete používat, už nikdy nebudete používat gprof nebo oprofile.
Viz Re:[PATCH] grep:neprovádějte externí grep u položek skip-worktree (2010-01-04)