まずはソースリストです。時間計測に
より間隔を短く&細かく設定したい場合には、Linuxのソースを数文字変更(0をひとつ足すなど)すれば希望通りになります。
その話のまえに、Linuxカーネルの動作の解析をしておきます。いわば、本手法の原理にあたる部分です。
なんでもいいから早く試してみたいという方は、カーネルソースを再構築用に展開し
(各ディストリビューションのマニュアルをご確認下さい)、
いくらか周期設定に制限はあるようですが、その周期そのものはフィードバック制御などにはそこそこつかえます。
つまり、いまのままでも、周期 20[ms] でよければ、すぐに制御に使えます。
(Alpha用Linux以外の PC-AT系、LinuxPPC、Sparc などの場合、Linux2.6以降はx86でも1ms単位?)
さて、その選定条件ですが、基本的には
この持ち時間は次に述べるタイマ割り込みのときにCPUを使用していたプロセスから減らしていきます。 つまりCPUを使い続けるようなプロセスはどんどん持ち時間が減り、結果的に時々実行可能状態になるようなプロセスより実質的な優先度が下になります。 それに対して、タイマ割り込みになる前に sleep などでCPUをOSに返してしまえば、CPUは使っていても持ち時間そのままなので、実行可能状態に戻れば、CPUをもらいやすいことになります。
ちなみに、実行可能状態にあるプロセスの持ち時間がすべて0になると持ち時間の再計算が行われます。それはすべてのプロセスに対して
これらのことから、
このタイマ割り込みで行う処理は
Linux の場合、
少し処理をして、タイマ割り込みが来る前 sleep で休眠するようなプロセスは、スケジューリングのところで述べたように、基本的に持ち時間は高くなっています。
その結果、CPUを得やすいわけです。その結果が上のグラフになります。
多少乱れが生じているのは、カーネルそのものタイマ割り込み時の処理量に変動があったり、システムコール中だったりするためと考えられます。
さて、タイマ割り込みで同時に複数のプロセスが実行可能状態になったら、どうなるでしょうか。
そのときはもちろん、持ち時間の多い方が優先です。
UNIXにおいては、多くのプロセスが走っていますが、実はそのほとんどが休眠状態です(サーバプロセスで要求町待機)。
つまり、目的の制御用に周期的に実行しているプロセスの他のプロセスが起きてしまったらそっちにCPUをとられる可能性があります。
CPUを得たプロセスが単純な処理ならいいのですが、最悪の場合は次のタイマ割り込みまでCPUが得られないということがあり得ます(それどころか、そのさき2〜3回ということも)。
この状態を回避するには、最初から持ち時間を多くしておくに限ります。具体的には
このような仕掛けによって、一見いいかげんなプログラムで、タイマ割り込みで量子化された周期で、周期的に処理を実行することが可能なのです。
この方法が、いい加減なように見えて期待通り動くのは、このようにOSの動作が都合良く設計されていたためですが、逆にOSの動作が
分かってしまったので、いい加減な方法ではなく、理論に基づいた手法となったのです。
ことです。
(jiffies, 時刻変数, load average など)
にスケジューラが呼ばれます。
(前2者の参考:
つまり、タイマ割り込みで休眠プロセスが起こされたとき、
ことになります。
理想的には全プロセスが休眠しているか、現在実行状態のプロセスがユーザ空間で実行されていれば、一定時間 sleep しつつ動作するようなプログラムは、タイマ割り込みの精度(+カーネルの仕事時間)で周期的に実行されることになります。
システムコールが実行されている場合は、そのシステムコールの処理時間だけ遅れが発生します。
(数字が多いほどniceである、ということは-20というのはある意味極悪)
優先度は root でなければ負の値は設定できませんが、I/Oポートなどを操作しようと思ったら、やはり root でなければならないので、それはそれでよしとしましょう。
いっそのことプログラム中に