Priority
oldPriority=Priority([newPriority])
ここではPriority = 優先度とします。
スクリプトの実行の優先度を 'newPriority' に設定します。また、非リアルタイムスケジューリングから、リアルタイムスケジューリングに移行します。(ただし、 'newPriority' が0よりも大きい場合)
訳注)スケジューリングについてはかなり専門的な話になります。ここに記載している内容だけでは不十分ですので、こちらのリアルタイムに関する項などを参考にされることをお勧めします。
優先度を高く設定していると、他のアプリケーションやシステムのプロセスが、実験プログラムの挙動(時間制御の面で)を妨害する確率を下げることができます。(もしくは妨害があったとしても)その影響を少なくすることができます。しかし、お使いのコンピューター(その他ハードウェアも含めて)の時間制御には様々な要因がからんでくるため、Priority関数で改善されるのは一部分だということに注意をしてください。PsychDocumentationフォルダやWikiのページに、時間制御に関する情報がたくさんあるので、そちらも参照してください。ちなみにLinux上でプログラムを動かす場合が最も時間制御がよくなります。その次に精度がよいのがMac上で動かす場合です。
Mac OS X について
OS 9やWindowsとちがって、OS Xで優先度を高く設定した場合には、キーボードや ハードドライブのような重要なハードウェアには影響を与えないようになっています。Priority関数は実際にはMachSetPriority関数(これはMEXファイル)を呼び出しますが、ふつうは単純にPriority関数を使ってください。特別な理由があるときだけMachSetPriority関数を使ってください。
Priorityを0よりも大きな値に設定した場合、MatlabがCPUを独占する時間を制限する必要があります。(訳注:Priorityを高く設定している場合、それが有効な時間が限られているため、定期的に他のプロセスにCPUを明け渡す必要があるということだと思われる)もしこの制限がうまくいかなかった場合には、OSによってPriorityは0に引き下げられるでしょう。現在の優先度を確認するには、引数なしでPriority関数を実行してください。
MatlabがCPUを独占する時間を制限する(MATLABによるCPUの独占をやめて他のプロセスに明け渡す)2つの方法について説明します。
- WaitSecs関数を呼んだとき
- Screen('Flip', ...)を呼んだとき
これら2つの関数を実行したときには、MATLABのメインスレッド(訳注:実験プログラムと思ってよいと思います) がスリープ状態となり、再び復帰するまでCPUが他のスレッドに渡されます。WaitSecs関数では指定した時間が経過するまで、Screen('Flip', ...)では次に画面が書き換わるまでスリープすることになります。
(訳注:例えばBublleDemoでは、while文の中で
WaitSecs(0.001);
を呼び出してシステムへの負荷を減らしています)
Priorityの値は、ビデオフレーム数(the video frame period) に比例しており、次の数式で表される時間のあいだは、MATLABがCPUを完全に独占することが保証されています。
GuaranteedCPUtimePerFramePeriod = priority/10 * framePeriod
もしフレームレートの異なる複数のディスプレイを使用している場合には、Priorityは、もっとも短いフレーム数(the shortest frame period)を選択します。
もし指定した独占時間を超えるような場合には、Macのカーネルがreal-time priority statusを無効にしてしまうでしょう。しかし、カーネルがどのような基準に基づいて無効にしてしまうのかは不明です。我々は、CPUを100% 使用している状態で、 CPUの利用時間をいくつに設定しているかに関わらず、Jaguar Machカーネル(たぶん Mac OS 10.2のこと)が2.5秒後にpriorityを無効にしたのを確認したことがあります。
注意点)Priorityを設定したあとに、ビデオフレーム(リフレッシュレート?)を変更した場合には、優先レベルを決定する際に使われる the framePeriod の値が実際の値と異なってしまいます。したがって、ビデオフレームの変更を先に行ってください。
Windowsについて
Windowsでは、優先度は "process priority levels" のことを意味します。具体的には次の3つがあります。
優先度0(Priority = 0)→ 標準の優先度
優先度1(Priority = 1)→ 高い優先度
優先度2(Priority = 2)→ リアルタイム優先度(real time priority level)
スレッドの優先度と結合して、PTBに関わるスレッドの優先度が決まります。
Windowsでは、各スレッドはラウンドロビン方式で(訳注:すべてのスレッドが順繰りで平等に)実行されますが、優先度が低いスレッドは、優先度が高いスレッドが待機状態でない場合にのみ実行されます。現在のところ、MATLABのプロセスをリアルタイム優先度に設定することによって、どんなタスクが先に実行されるかを確認できていません。
言い換えるとキーボード入力を妨害される可能性があります。例えば、優先度を2(リアルタイム)に設定している状況で、clutアニメーションを実行しているとき、強制終了である Ctrl + Alt + Delete キーが機能しないかもしれません。しかしながら、キーボードからの入力はメッセージキューには蓄積されるので、GetChar関数またはGetClicks関数で取得することは可能です(ただしこれらの関数もまた、優先度が2の状態で呼ばれていること)。
注意点)ここに書かれている内容がよく理解できない場合には、優先度を1よりも大きな値にはしないほうがよいでしょう。
Linuxについて
Priority関数を有効にするには、少なくとも一回は PsychLinuxConfiguration関数を呼び出して、指示通りに設定を行う必要があります。この関数は、DownloadPsychtoolbox またはUpdatePsychtoolbox を使ってPTBをインストールした場合には自動的に実行されますが、LinuxのパッケージマネージャーやNeuroDebian経由でPTBをインストールした場合には、手動でPsychLinuxConfigurationを実行する必要があります。
優先度の値としては、0から99までを取り得ます。0の場合は、標準的な、非リアルタイムなタイムシェアリング操作となり、他のアプリケーションからの割り込みがある場合があります(意訳)。0よりも大きな値の場合はリアルタイムモードとなり、MATLAB(またはOctave)のプロセスは、特定の優先度を持ったプロセスとして、動作のスケジュールが組まれます。より高い優先度ほどより正確な動作が見込めますが、その一方でシステムプロセスを妨害する可能性が高くなります。特に理由がない場合は、優先度を1にしておくことをお勧めします。たいていの場合は優先度を1にするだけで十分です。(他のリアルタイムアプリケーションを同じマシンで並行して動作させていて、PTBの優先度をそれらよりも高くしたいと思わない限り)
リアルタイムモードでは、PTBは仮想メモリマネージャーがMATLAB(またはOctave)が使用しているメモリを(ハード)ディスク上にpage out するのを防いで、物理的なRAMにlock down しようとします。(訳注:RAM上にデータがあるほうが動作が速い)この動作がうまくいけば望ましいことですが、古いLinuxではロックされたメモリのサイズの上限はRAMの半分に制限されているので、大きなRAMが必要になります。この場合にはPTBが警告を出力しますが、それ以外については影響はありません。リアルタイムスケジューリングは有効なままで、memory locking のメリットを享受できないだけです。
古いシングルプロセッサーでは、リアルタイムモードにする際に、割り込みができない無限ループを作らないように気をつけてください。さもないとパソコンを再起動しないといけなくなるかもしれません。
see also OS X: Rush
see also Windows: Rush
see also OS 9: Rush, ScreenTest, RushTest, LoopTest