プロセスのタイムスライスの値を計測する
タイムスライス
タイムシェアリング方式(時分割方式)でCPUにプロセスを割り当てる単位時間のことをタイムスライス(Time Slice)あるいはタイムクアンタム (Time Quantum)と呼びます(こちらも参照)。 タイムスライスはスケジューリング・ポリシー及びいくつかのカーネルのパラメータによっても変化します。 Linuxカーネルのスケジューリング・ポリシーにはLinuxの独自優先順位 ( SCHED_OTHER ) 、FIFO ( SCHED_FIFO ) 、RR ( SCHED_RR )、バッチ ( SCHED_BATCH )、アイドル ( SCHED_IDLE )[1]があります。 ここではどのような値を実際に取っているのか観察してみましょう。
chrtの確認
まずコマンドchrtを使ってカーネルにはどのようなスケジューラと、スケジューラが取るプライオリティの値を確認してみます。
% chrt -m SCHED_OTHER min/max priority : 0/0 SCHED_FIFO min/max priority : 1/99 SCHED_RR min/max priority : 1/99 SCHED_BATCH min/max priority : 0/0 SCHED_IDLE min/max priority : 0/0
コマンド chrt のオプションは次の通りです。
% chrt --help Show or change the real-time scheduling attributes of a process. Set policy: chrt [options] <priority> <command> [<arg>...] chrt [options] -p <priority> <pid> Get policy: chrt [options] -p <pid> Policy options: -b, --batch set policy to SCHED_BATCH -f, --fifo set policy to SCHED_FIFO -i, --idle set policy to SCHED_IDLE -o, --other set policy to SCHED_OTHER -r, --rr set policy to SCHED_RR (default) ..... For more details see chrt(1).
今回はタイムスライスの値を表示する短いプログラムを作成し、それをchrtを使って変化させてみます。
試してみるコマンドラインは次のような形式になります。
% sudo chrt <オプション> <オプションのもつ最小プライオリティ値> ./a.out
タイムスライスを表示するプログラム
プロセスに与えられているタイムスライスの値を表示するプログラムは次の通りです。
% cat rr.c #include <unistd.h> #include <stdio.h> #include <sched.h> void main(void) { struct timespec tp; sched_rr_get_interval(getpid(),&tp); /* timeslice of this process */ printf("%.2fms\n",tp.tv_nsec/1000000.0); } % gcc -O rr.c
システムコールsched_rr_get_interval(2)を使います。 システムのもつタイムスライスの時間は /proc/sys/kernel/sched_rr_timeslice_ms に入っています。デフォルトでは100 (100ms) ですがシステムによって変化します。 実際にプロセスに割り当てられているタイムスライスの値はsched_rr_timeslice_msで示される値そのものではありません。 たとえばデスクトップ環境として使用しているDebian 18.04.2 LTSでは次のようになりました。
$ cat /proc/version Linux version 4.15.0-46-generic (buildd@lgw01-amd64-038) (gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)) #49-Ubuntu SMP Wed Feb 6 09:33:07 UTC 2019 $ cat /proc/sys/kernel/sched_rr_timeslice_ms 100 $ ./a.out 20.00ms
どう変化するのか実験
まずシステムのタイムスライスの値をデフォルト(100ms)の状態でテストしてみます。
$ ./a.out 20.00ms
値は20msでした。この値は実際にこのプロセスに与えられたタイムスライスの値です。時間はミリ秒です。 ではchrtを使ってスケジューリング・ポリシーを変更してみます。優先度はそのスケジューリング・ポリシーのもつ最低の値を与えています。
$ cat /proc/sys/kernel/sched_rr_timeslice_ms 100 $ ./a.out 20.00ms $ sudo chrt -v -o 0 ./a.out pid 8703's new scheduling policy: SCHED_OTHER pid 8703's new scheduling priority: 0 20.00ms $ sudo chrt -v -b 0 ./a.out pid 8705's new scheduling policy: SCHED_BATCH pid 8705's new scheduling priority: 0 20.00ms $ sudo chrt -v -i 0 ./a.out pid 8707's new scheduling policy: SCHED_IDLE pid 8707's new scheduling priority: 0 20.00ms $ sudo chrt -v -r 1 ./a.out pid 8709's new scheduling policy: SCHED_RR pid 8709's new scheduling priority: 1 100.00ms $ sudo chrt -v -f 1 ./a.out pid 8711's new scheduling policy: SCHED_FIFO pid 8711's new scheduling priority: 1 0.00ms
システムで設定しているデフォルトのタイムスライスは100msです。 デフォルト(何もせずに)実行した際のタイムスライスの値は20.00ms、そしてSCHED_OTHERも20.00msです。これはLinuxのカーネルのデフォルトのスケジューリング・ポリシーがSCHED_OTHERなので一致しています。ここではSCHED_OTHER、SCHED_BATCH、SCHED_IDLEは20.00msですが、繰り返し実行しているとSCHED_BATCHが4.00msとなるケースもあり、SCHED_BATCHは内部の諸条件によって変化しているのが観測できます。 SCHED_RRは100.00msです。これはsched_rr_timeslice_msの値が反映されています。 SCHED_FIFOは常に0.00ms、つまりタイムスライスの値が設定されません。最優先でCPUに割り当てられ一度割り当てられたらば、タイムシアリング処理は行われず、その処理が終わるまでCPUが割り当て続けるということになります。
脚注
- ↑ カーネル4.4.0ではこの通りですが、将来にこれ以外にも増える可能性はあります。