優先度に基づくスケジュールモデルを理解する
- 更新日2025-02-20
- 11分で読める
このトピックでは、LabVIEW Real-Timeモジュールで、スレッドの作成時とスケジュール設定時において優先度と実行システムがどのように処理されるかを説明します。優先度に基づくスケジュールを理解することで、確定的アプリケーションの作成時にLabVIEW Real-Timeモジュールの長所を活用することができます。
スレッド、優先度、および実行システム
LabVIEWは、複雑なコンピュータ演算の多くを概念化することで直感的に操作できるグラフィカルプログラミング環境を実現する構造化されたデータフロー言語です。LabVIEWにおいて並列タスクのスケジュールが優先度に基づいて決定されるしくみを説明するために、まずスケジュールプロセスの基本となる重要な概念を明確にします。
- スレッド―LabVIEW Real-Timeモジュールにおける並列処理の基本単位。スレッド内の操作はシーケンス的に実行されますが、各スレッドは独立して実行されます。
- スケジューラ―オペレーティングシステムがスレッドのスケジュールに使用するアルゴリズム。スケジューラは、システム内の各CPUでその時々に実行するスレッドを決定します。
- 実行キュー―スケジュール可能なスレッドのキュー。
- プリエンプティブスケジューリング―スケジューラが、高い優先度のスレッドが実行可能になるとすぐに低い優先度のスレッドに割り込むプロセス。
- ラウンドロビンスケジューリング―同じ優先度のスレッドが均等なプロセッサ時間を使用するよう、それらのスレッドがスケジューラによって周期的に切り替えられるプロセス。
- 実行システム―関連するスレッドのプール。VIの実行システムの構成は、VIプロパティダイアログボックスの実行ページで行います。
- VI優先度―VIプロパティダイアログボックスの実行ページでVIに割り当てる優先度。
- タイミングループの優先度―優先度入力またはタイミングループを構成ダイアログボックスを使用してタイミングループに割り当てる優先度。
- OS優先度―リアルタイムオペレーティングシステムによってスレッドに割り当てられる優先度。LabVIEWは、所有VIまたはタイミングループの優先度を元に各スレッドにOS優先度を割り当てます。
- タイムクリティカル―LabVIEW VIに設定される最高の優先度。タイムクリティカルスレッドは、スケジューラの優先度よりも優先して実行されます。したがって、タイムクリティカルスレッドは完了するまで、またはブロック状態になるまで実行されます。
- 優先度の継承―スレッドが一時的に発呼者スレッドの優先度となるプロセス。優先度の継承により、優先度の逆転を防止することができます。
- ジッタ―確定的システムで期待されるパフォーマンスと実際の実行タイミングのずれ。
以下の図は、LabVIEWで使用される優先度と実行システムを示しています。
上記の図は、以下の点を示します。
- 実行システムは優先度レベルとは独立しています。LabVIEWは、実行システムをスレッドプールとしてのみ使用し、実行システムを元にスレッドの優先度を決定することはありません。各実行システムで、それぞれの優先度で4つまでのスレッドが作成されます。この規則はマルチCPUシステムの各CPUにも適用されるため、デュアルコアシステムでは各実行システムの各優先度で8個までのスレッドが作成されます。各実行システムのスレッド数には限りがあるため、実行システムの割り当てのバランスを図ることが重要となり得ます。1つの実行システムに過度に多くのVIを割り当てると、それらのVIはスレッドを共有する必要があるため、VIの潜在的な並列性を制限することになります。
- ただし、タイミングストラクチャ優先度はすべて、VI優先度レベルの高優先度とタイムクリティカルの間に位置します。
- 並列コードを1つのタイミングストラクチャ内に配置すると、各タイミングストラクチャは1つのスレッドで実行されるため、そのコードは直列化されます。
- LabVIEW Real-Timeモジュールシステムには、ユーザのLabVIEW VIを構成するスレッドと並列実行される多くのシステムスレッドが含まれます。これらのシステムスレッドは、様々な優先度で実行されます。たとえば、NIスキャンエンジンスレッドが実行されている場合、デフォルトではタイムクリティカルより上の優先度で実行されます。
優先度の継承
LabVIEWでは、意図しない優先度の低下を防ぐため、優先度の継承が行われます。サブVIが発呼者VIよりも低い優先度で構成されており、かつ両方が同じ実行システム内で実行される場合、そのサブVIは発呼者VIの優先度を継承します。サブVIが発呼者VIよりも高い優先度で構成されている場合、そのサブVIは構成された優先度を維持します。
リアルタイムオペレーティングシステム (RTOS) も優先度を継承します。優先度の高いスレッドが必要とする共有リソースを優先度の低いスレッドが占有すると、RTOSは共有リソースを占有しているスレッドの優先度を一時的に高くして、優先度の高いスレッドにリソースがすぐに返されるようにします。
タイムクリティカル優先
タイムクリティカルスレッドには2つのタイプがあります。
- タイムクリティカル優先度のVI―タイムクリティカルに設定されたVIは、スケジューラの優先度よりも優先して実行されます。したがって、タイムクリティカルに設定されたVIは常に完了するまで、またはタイミング関数または外部イベントを待機する関数によってブロック状態になるまで実行されます。
- タイミングストラクチャ―優先度の高い他のタイミングストラクチャまたはタイムクリティカルに設定されたVIがタイミングストラクチャに割り込む場合があります。
タイミングストラクチャ優先度
LabVIEWでは、VI優先度とタイミングストラクチャ優先度という2つの独立した、かつ互いに関連する優先度スキームが使用されます。タイミングストラクチャ優先度は数値で表され、ターゲット上で実行される他のタイミングストラクチャに対し、値が高いほど優先度が高いことを示します。ただし、タイミングストラクチャ優先度はすべて、VI優先度レベルの高優先度とタイムクリティカルの間に位置します。
優先度スキーム使用時のエラーを防ぐ
以下の例に示すように、お使いのアプリケーションでは優先度スキームを1つだけ使用することをお勧めします。
- アプリケーション内でタイミングストラクチャを使用する場合、すべてのVIを低優先度に設定してください。
- 優先度がタイムクリティカルに設定されたVIをアプリケーションで使用する場合は、優先度がタイムクリティカルに設定されたVIの内側にタイミングストラクチャを配置しないでください。
1つの優先度スキームに統一することでアプリケーションの可読性が向上し、エラー発生の可能性を少なくすることができます。
スケジュール
スケジュールとは、その時々にどのタスクを実行するかを決定するプロセスです。スケジュールは、現行のあらゆるオペレーティングシステムにおいて重要なタスクですが、リアルタイムオペレーティングシステム (RTOS) では、特別重要なタスクです。VIが生成するスレッドに加えて、RTターゲットは多くのOSスレッドとドライバスレッドを様々な優先度で実行します。タスクがタイミング要件に従って実行されることを確実にする上で、LabVIEW Real-Timeがスレッドのスケジュールを設定する方法について理解するのは有益です。
RTスケジュールの基本規則
以下の規則は、新しいスレッドが実行キューに追加された時のLabVIEW Real-Timeスケジューラの動作を示しています。
- 優先度が異なるスレッド間ではプリエンプティブスケジューリングを実行する。
- 優先度が等しいスレッド間ではラウンドロビンスケジューリングを実行する。
- タイムクリティカルスレッドは完了するまで実行する。
LabVIEW Real-Timeモジュールスケジュールのしくみ
システムの各スレッドは、実行中かブロック状態のいずれかの状態です。
- 実行中―スレッドは実行キューの中にあります。これは、スレッドが実行可能状態または実行中であることを意味します。
- ブロック―スレッドは、I/O操作やタイミング関数の完了などのイベントが発生するまで実行できません。
スレッドの実行が開始されると、スレッドは以下の条件のいずれかが発生するまで実行されます。
- Whileループ内の「待機」VI、タイミングループの標準タイミング機構、または「タイムアウト付きで変数を読み取る」関数などのブロック関数によって、スレッドがブロック状態になる。
- 優先度の高いスレッドがスレッドに割り込む。
- スレッドが実行を完了する。
スレッドのブロックが解除されると、実行キューに追加されます。実行キューは常に優先度の順番に並べられるため、スレッドがこのキューに入るとそれより優先度が低いすべてのスレッドより先に配置されます。実行キューに追加されたスレッドの優先度が現在実行中のスレッドよりも高い場合、その優先度の高いスレッドは異なるCPUコアで実行されるか、またはプリエンプティブスケジューリングプロセスにおいては現在実行中のスレッドに割り込みます。
プリエンプティブスケジューリング
プリエンプティブスケジューリングは、スレッドの実行順序を各スレッドの相対的な優先度に基づいて決定するプロセスです。現在のスレッドよりも優先度が高いスレッドが実行キューに追加されると、スケジューラは必要に応じて、優先度が高いスレッドが即時実行できるように現在のスレッドに割り込みます。割り込まれたスレッドは実行キューに戻り、優先度の高いスレッドの後ろに追加されます。
ラウンドロビンスケジューリング
ラウンドロビンスケジューリングは、各スレッドがほぼ同じCPU時間を使用できるようスレッド間で切り替えるプロセスです。ラウンドロビンスケジューリングでは、スケジューラは各スレッドに与えられるCPU時間を追跡し、等間隔でスレッドに割り込んで切り替えます。
LabVIEW Real-Timeモジュールでは、優先度が等しいスレッド間ではラウンドロビンスケジューリングが実行されます。ただし、LabVIEW Real-Timeモジュールは、優先度がタイムクリティカルに設定されたVI間ではラウンドロビンスケジューリングを実行しません。
ループの優先度をタイミング要件に基づいて設定する
重要なループから順に高い優先度を設定する方法は自然に思われますが、この方法ではジッタが発生する可能性があります。アプリケーションでのタスクの重要度ではなく、タスクが特定のタイミング要件を満たすことの重要性に基づいて各ループの優先度を設定します。たとえば、データ収集ループとロギングループを持つデータロギングアプリケーションで、ロギングループの優先度を高くすることを考えたとします。ただし、データ収集はデータポイントの損失を回避するために、一定の間隔で行われる必要があります。ここで、各データポイントをディスクにログするタイミングは、最終的に各データポイントがログされる限り重要ではありません。この場合、アプリケーションの主な目的がデータロギングであっても、データ収集ループに高い優先度を割り当てる必要があります。