統計収集

統計収集

私はCPUコアで実行されるスレッドを持つ単純なプログラムを書いています。わずかに積極的に回転し、CPUコアを100%使用します。top+でこれを見ることができます1

N分後に次のことを知りたいです。

カーネルは実行中のスレッドを何度もプリエンプション(中断)しますか?

答え1

これはLinuxイベントフックの目的であり、次のものと組み合わせることができます。perf

統計収集

簡単なものから始めましょう。

sudo perf state -e sched:sched_switch yourprogram 

この試み:

busyloop.c

#include <stdint.h>
int main()
{
    for (volatile uint_fast64_t i = 0; i < (1ULL<<34); ++i) {
    }
}

編む:

gcc -O3 -o busyloop busyloop.c

ランニング:

$ sudo perf stat -e sched:sched_switch ./busyloop

 Performance counter stats for './busyloop':

               134      sched:sched_switch

      26.534402995 seconds time elapsed

      26.496337000 seconds user
       0.000996000 seconds sys

それがあなたの答えです。その時のスケジュールが変わります。これには、プロセスが中断されることなくカーネル自体に入ることが含まれます。

sched_switchシステムコールの入力回数とその両方を指定したときに取得する数値を減算します。

$ sudo perf stat -e sched:sched_switch,raw_syscalls:sys_enter ./busyloop

 Performance counter stats for './busyloop':

               765      sched:sched_switch
                30      raw_syscalls:sys_enter

      26.528107216 seconds time elapsed

      26.473054000 seconds user
       0.002994000 seconds sys

負荷の高いこの例では、765個のコンテキストスイッチがありましたが、そのうち30個だけがシステムコールを実行するプロセス自体が原因で発生しました。

リアルタイム統計

perf stat同じコマンドラインオプションを使用してリアルタイムで実行できることを確認することもしばしば可能です。perf top

./busyloop &
sudo perf top -e sched:sched_switch,raw_syscalls:sys_enter -p $!

perf top、、、観察する指定されたイベントなしでかなり驚くべきことを行います。CPUコアがどの機能にどのくらいの頻度であるかを観察します。これは実際のワークロード状況に最適化されています。ソフトウェアのための素晴らしいperf record最初のステップperf reportですが、これは長い道のりにつながります。することができます)

深い追跡

非常に詳細が必要な場合は、perf schedこれは驚くほど強力なツールです。

$ # make a recording
$ sudo perf sched record -- ./busyloop
[ perf record: Woken up 75 times to write data ]
[ perf record: Captured and wrote 161,058 MB perf.data (1458691 samples) ]
$ # evaluate the recording
$ sudo perf sched map
  *A0                               179778.272339 secs A0 => migration/0:17
  *.                                179778.272347 secs .  => swapper:0
   .  *B0                           179778.272413 secs B0 => migration/1:21
   .  *.                            179778.272419 secs
   .   .  *C0                       179778.272494 secs C0 => migration/2:26
   .   .  *.                        179778.272503 secs
   .   .   .  *D0                   179778.272576 secs D0 => migration/3:31
   .   .   .  *.                    179778.272585 secs
   .   .   .   .  *E0               179778.272659 secs E0 => migration/4:36
   .   .   .   .  *.                179778.272670 secs
   .   .   .   .   .  *F0           179778.272714 secs F0 => migration/5:41
   .   .   .   .   .  *.            179778.272733 secs
   .   .   .   .   .   .  *G0       179778.272815 secs G0 => migration/6:46
   .   .   .   .   .   .  *.        179778.272821 secs
   .   .   .   .   .   .  *H0       179778.272948 secs H0 => perf-exec:1315372
………

ここで、各列は CPU コアであり、各行はイベントです。man perf-sched私よりも詳細に説明できます。perf schedule latencyログを取得し、スケジュール内の各タスクの実行がどれだけ遅れたかを通知します。

$ sudo perf sched latency | grep busyloop
  busyloop:1315372      |  26548.094 ms |      677 | avg:   0.055 ms | max:   0.660 ms | max start: 179800.883053 s | max end: 179800.883713 s

とても簡単です!

関連情報