プロセスその15

さて、この遷移状態に沿ってProcessなりThreadはスケジューリングされるわけだが、このスケジュールの時間間隔をQuantumと呼ぶ(上巻P398)。これを"Quantum"と呼ぶあたりはVMSと全く同じである。また、Quantumの取り扱い方法も極めて似ている。ちょっとVMSを例に説明してみよう。

VMSの場合、Quantum(VMSでは大文字である)の初期値はSYSGEN ParameterのQUANTUMの値が利用される。このQuantum値は2つの意味があり、一つはそこで示される時間間隔の間はCPUリソースが利用できる(明示的に放棄する場合を除く。これは後述)事と、ProcessがInswapされてから、最低でもこの時間間隔の間はメモリ内にあることが保障されることだ。Quantumのデフォルト値は20で、VMSの場合これに10m secondsを掛けた200msecというのがスケジューリングのインターバルとなる。ただしProcess HeaderのPHD$W_QUANTというフィールドには、-20がセットされている。

CPUは10msec毎にタイマー割り込みを発生させるが、その割り込みルーチンの中で先のPHD$W_QUANTフィールドをincrementしてゆく。その結果、PHD#W_QUANTフィールドが0もしくは正の値になったら、再スケジューリングが発生する事になる。ちなみにこれにはちょっと例外が付く。CUR状態のProcessがI/O Wait状態になった場合、そのたびにSYSGEN ParameterのIOTAというパラメータの分だけQuantumが減らされる事になっている。IOWAはデフォルトで2であり、つまりI/O Waitに一回陥るたびにQuantumが20msづつ少なくなってゆく訳だ。これはちょっと考えれば合理的であるのがお分かりいただけよう。CPU BoundaryなProcessの場合、CPU時間は長ければ長いほど処理の効率が上がる。Process Schedulingに伴い発生するContext Switchingは、システム全体とすれば単にオーバーヘッドでしかないから、この頻度を減らすほうが全体のスループット向上に役立つ。対してI/O BoundaryなProcessは、むしろ積極的にContext Switchingを行ったほうがI/Oのスループット向上が可能だ。勿論全てのプロセスがある特定のデバイスのI/O「だけ」をやっているなんてケースでは無意味だろうが、様々なProcessが様々なデバイスに対して同時にI/Oを掛けているというケースでは、Context Switchingの頻度を上げたほうが効果的である。Context Switchingに関するこの2つの相反する要求をうまく調整するのが、IOTAというパラメータな訳だ。

さて、一旦Quantumを使い切った場合、KernelはQuantum-endというソフトウェア割り込みを発生させ、これによりSCH$QENDというサブルーチンが呼び出される。このルーチンは対象となるProcessと同じCPU上で実行されるが、処理そのものはKernel、それも先にちょっと触れたタイマー割り込みのISRの一部として実行される。SCH$QENDは

  • PHD$W_QUANTの値を初期化(つまり-20に)する
  • プロセスの実行時間カウンタの値(これはProcess Header内に存在)をUpdate
  • initial quantum flagをクリア(これは実行状態に無くなった事を示す)

といった作業に加え、Process実行履歴のUpdateとか、Process実行時間リミットに達したか(これはProcess毎に使える実行時間が制限されている場合のみ、行われる)のチェックと必要ならプロセス削除、もし可能ならWorking Set Adjastmentの開始、COMO状態のプロセスがあった場合、そのプロセスのinswap作業の開始、といった事が行われる。またこの時点で、COM状態で自Processと同等以上のPriorityを持つProcessがあるかどうかを確認し、無ければ再び自Processの実行を再開する。といった作業が行われる。Processの再スケジュールそのものはSchedulerというプロセスがIPL=3で実行することになっているので、SCH$QENDはIPL=3の割り込みを発生させるだけであり、あとはSCH$QENDが終了するとInterrupt Handlerにより即座にSchedulerが動くわけだ。

ここでちょっと面白いのは、SCH$QENDの最後のPriorityの制御だ。自ProcessがBase Priority以上で動作している場合、一時的にPriorityを下げるという作業が入る事だ。例えば自分がPriority 5の状態で、それとは別に沢山のPriority 4のProcessがあった場合、原理から言えば自Processがずっと動き続け、Priority 4のProcessは待たされ続ける事になる。ただこれがあまりに長い期間続くのは、システム全体の使い方として好ましくない場合が多い。勿論Priority 4のProcessが何らかのWAITに入っているのなら問題はないが、COM状態でプロセスが待機し続けているなんていうのは、不公平感がある。そこで、Priority上位のものが常にCPUを独占し続けるのではなく、多少低いPriorityのProcessにもCPUを分配する、という仕組みが設けられている。それが、一時的にPriorityを下げるという仕組みな訳である。