Giám sát các cuộc gọi CPU / hệ thống trong Linux


9

Tôi có một vài quá trình đang ngốn rất nhiều thời gian của CPU hệ thống (như được xác định bằng cách xem vmstat). Có cách nào dễ dàng để tìm ra loại cuộc gọi hệ thống nào đang được thực hiện không?

Tôi biết có bước đi, nhưng có một cách nhanh chóng và dễ dàng hơn? Có tồn tại một cái gì đó như một "hàng đầu" cho các cuộc gọi hệ thống?


1
strace là giải pháp.
Warner

Câu trả lời:


15

Tôi nghĩ rằng bước đi với -ccờ có lẽ là gần nhất mà tôi biết. Nếu bạn chưa sử dụng -ccờ, hãy thử điều này:

$  sudo strace -c -p 12345

Trong đó 12345 là ID tiến trình (PID) của quy trình được đề cập. Lưu ý rằng việc phân tầng một quy trình sẽ thêm chi phí bổ sung, vì vậy trong khi bạn truy tìm quy trình đó, quy trình sẽ chạy chậm hơn.

Sau khi chạy trong bao lâu bạn muốn thu thập dữ liệu, nhấn Ctrl-Cđể dừng thu thập dữ liệu của bạn và xuất kết quả. Nó sẽ tạo ra một cái gì đó như thế này:

% 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

Như bạn có thể thấy, đây là bảng phân tích tất cả các cuộc gọi hệ thống được thực hiện bởi ứng dụng, được sắp xếp theo tổng thời gian và bao gồm thời gian trung bình cho mỗi cuộc gọi và số lượng cuộc gọi cho mỗi tòa nhà. Nếu bạn muốn sắp xếp chúng theo cách khác nhau, hãy xem trang hướng dẫn để biết, vì có một vài lựa chọn.


2
Chết tiệt, mutex vô ích! lắc nắm đấm
Gaius

2

Có thể thử một trong các trình biên dịch lấy mẫu, chẳng hạn như oprofile hoặc cho các nhân mới hơn, perf. Nếu bạn may mắn, "perf top" có thể cho bạn biết chính xác những gì bạn muốn. Xem ở đây để biết một số ví dụ


2

Loại công tắc strace mà tôi có xu hướng sử dụng là cái này.

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

Một ví dụ về điều này sẽ giống như,

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>

Bạn thấy sự khác biệt về thời gian ở phía bên phải của cuộc gọi hệ thống cho biết thời gian cần thiết để chuyển từ cuộc gọi hệ thống này sang cuộc gọi khác.

Nó sẽ bắt bạn chênh lệch múi giờ giữa các cuộc gọi hệ thống. Vì vậy, khi bạn thấy rằng một cuộc gọi hệ thống có khoảng cách khá vài giây với cuộc gọi hệ thống tiếp theo, thì nó sẽ gây ra một số tiếng ồn.

Một phương pháp khác là coredump nó với gcore. Tuy nhiên, điều đó đòi hỏi một chút kinh nghiệm điều hướng qua gdb.

Nhưng, nếu luồng là một luồng nhân, thì bạn không thể thoát hoặc bỏ qua nó. Trong trường hợp đó, chúng ta phải sử dụng một cái gì đó phức tạp hơn. Trong kernel RHEL5, chúng tôi sử dụng oprofile. Trong RHEL6, chúng tôi sử dụng perf. Tôi thích sự hoàn hảo hơn oprofile. Dữ liệu hoàn hảo có thể được thu thập với biểu đồ như định dạng hiển thị cuộc gọi hệ thống trong đó phần trăm tối đa của CPU đang được sử dụng.

Với một thử nghiệm hoàn hảo, tôi thấy điều này.

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   

Nó cho thấy chức năng kernel trong đó 38% thời gian CPU đang được sử dụng. Bây giờ, chúng ta có thể kiểm tra chức năng và xem nó đang làm gì và nó phải làm gì.

Với một vài ví dụ, nó không khó lắm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.