Монітор системних процесорів / системних викликів в Linux


9

У мене є кілька процесів, які споживають багато системного процесорного часу (як визначено, дивлячись на vmstat). Чи є простий спосіб дізнатися, які саме системні дзвінки здійснюються?

Я знаю, що існує напруга, але чи є швидший і простіший шлях? Чи існує щось на кшталт "вершини" для системних дзвінків?


1
strace - це рішення.
Warner

Відповіді:


15

Я думаю, що страйк із -cпрапором, мабуть, є найближчим мені відомим. Якщо ви ще не використовували -cпрапор, спробуйте це:

$  sudo strace -c -p 12345

Де 12345 - ідентифікатор процесу (PID) відповідного процесу. Зауважте, що розшарування процесу додає додаткові накладні витрати, тому, поки ви його відстежуєте, процес буде працювати повільніше.

Після того, як ви хочете збирати дані, натисніть, Ctrl-Cщоб зупинити збір даних та вивести результати. Це створить щось подібне:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 31.88    0.001738         145        12           futex
 16.79    0.000915          11        80           tgkill
 12.36    0.000674          34        20           read
  9.76    0.000532         266         2           statfs
  8.42    0.000459          13        35           time
  4.38    0.000239           6        40           gettimeofday
  3.65    0.000199           4        48           sigprocmask
  2.94    0.000160          18         9           open
  2.88    0.000157          12        13           stat64
  1.32    0.000072           9         8           munmap
  0.90    0.000049           6         8           mmap2
  0.88    0.000048           3        14         7 sigreturn
  0.79    0.000043           5         9           close
  0.77    0.000042           4        10           rt_sigprocmask
  0.64    0.000035           3        12           setitimer
  0.55    0.000030           5         6         6 rt_sigsuspend
  0.53    0.000029           4         8           fstat64
  0.29    0.000016           8         2           setresuid32
  0.13    0.000007           4         2           _llseek
  0.09    0.000005           3         2           prctl
  0.04    0.000002           2         1           geteuid32
------ ----------- ----------- --------- --------- ----------------
100.00    0.005451                   341        13 total

Як бачимо, це розбиття всіх системних дзвінків, здійснених програмою, відсортованих за загальним часом та включаючи середній час на виклик та кількість викликів за кожен системний виклик. Якщо ви хочете сортувати їх по-різному, перегляньте довідкову сторінку про напругу, оскільки є кілька варіантів.


2
Чорт забирай вас, марний мутекс! струшує кулак
Гай

2

Можливо, спробуйте один із профілів вибірки, наприклад, oprofile або для нових ядер, perf. Якщо вам пощастить, "perf top" може точно сказати вам, що ви хочете. Дивіться тут кілька прикладів


2

Тип тягових вимикачів, якими я схильний користуватися, це такий.

strace -ffttT -p pid -o /tmp/strace.out

Приклад цього виглядає так:

19:35:57.485493 mprotect(0x7f35e7472000, 16384, PROT_READ) = 0 <0.000037>
19:35:57.485599 mprotect(0x7f35e7692000, 4096, PROT_READ) = 0 <0.000030>
19:35:57.485697 mprotect(0x7f35e78b7000, 4096, PROT_READ) = 0 <0.000030>
19:35:57.485782 munmap(0x7f35e7896000, 129588) = 0 <0.000037>
19:35:57.485875 set_tid_address(0x7f35e78949d0) = 10730 <0.000029>
19:35:57.485960 set_robust_list(0x7f35e78949e0, 0x18) = 0 <0.000024>
19:35:57.486048 futex(0x7fff8f58628c, FUTEX_WAKE_PRIVATE, 1) = 0 <0.000025>
19:35:57.486131 futex(0x7fff8f58628c, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME, 1,       NULL, 7f35e7894700) = -1 EAGAIN (Resource temporarily unavailable) <0.000024>

У правій частині системного виклику ви бачите різницю в часі, яка показує, скільки часу пішло від одного системного дзвінка до іншого.

Це вловить різницю у часі між системними дзвінками. Отже, коли ви бачите, що системний виклик має достатньо декількох секунд розриву з наступним системним викликом, тоді він видає шум.

Інший метод полягає в тому, щоб скорегувати його з gcore. Однак для цього потрібен невеликий досвід навігації по gdb.

Але, якщо нитка є ниткою ядра, то ви не можете її напружити або перенастроїти. У такому випадку ми повинні використовувати щось складніше. У ядрі RHEL5 ми використовуємо oprofile. У RHEL6 ми використовуємо perf. Я віддаю перевагу perf над oprofile. Дані Perf можуть бути зібрані у графічному форматі, що показує системний виклик, де використовується максимальний відсоток процесора.

З тестовим парфумом я це бачу.

38.06%  swapper  [kernel.kallsyms]  [k] mwait_idle_with_hints                                                                                                               ↑

29.45%  swapper  [kernel.kallsyms]  [k] read_hpet 
4.90%  swapper  [kernel.kallsyms]  [k] acpi_os_read_port                                                                                                                   ▒
4.74%  swapper  [kernel.kallsyms]  [k] hpet_next_event   

Він показує функцію ядра, на яку витрачається 38% часу процесора. Тепер ми можемо перевірити функцію і побачити, що вона робить і що вона повинна робити.

Маючи кілька прикладів, це не так вже й важко.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.