ジッタを回避する
- 更新日2025-02-20
- 8分で読める
正確なタイミングは、リアルタイムアプリケーションの動作に不可欠な要素です。確定的システムで期待されるパフォーマンスと実際の実行タイミングのずれを、ジッタと呼びます。このトピックの情報は、RTアプリケーションのジッタの最小化に役立ちます。
ジッタの一般的な原因を回避する
ジッタを最小化するには、タイムクリティカルループに非確定的操作を含まないようにします。一般的なジッタの原因には、以下が挙げられます。
- メモリの割り当て―確定的ループで使用する配列には事前にメモリを割り当て、また確定的ループでの可変サイズのデータストラクチャの使用を避けます。事前に割り当てられた配列を確定的ループ内で操作するには「部分配列置換」関数を使用します。メモリ管理操作を示すメモリ待機システムイベントフラグを特定するには、Real-Time Trace Viewerを使用します。
- リファレンスを開く/閉じる―確定的ループに入る前の初期化段階でリファレンスを開き、確定的ループが終了した後のシャットダウン段階でリファレンスを閉じます。リファレンスを開いたり閉じたりする操作は、ループの確定性に影響する可能性があります。
- 通信―確定的ループを使用して通信する際は、RT FIFO関数またはReal-Time FIFOが有効化されたシェア変数を使用します。RT FIFOは、確定的ループが優先度の低いループにブロックされずにデータにアクセスできるよう、データをバッファします。
- 共有リソース―確定的ループとその他のループによるハードウェアリソース、I/Oチャンネル、非再入可能VIなどの共有リソースへのアクセスを回避します。共有リソースの争奪は、ジッタのよくある原因です。確定的ループは、他のループでも使用されるハードウェアリソースや非再入可能VIを使用すると、他のループが共有リソースを解放するまで待機しなければならない可能性があります。
- ファイルI/O―確定的ループ内でのファイルI/O操作を回避します。ハードディスクアクセスによって、確定的ループで制限のないジッタが発生する可能性があります。
- 非同期I/O―タイミングループまたはタイムクリティカルVI内で非同期I/O処理を回避します。LabVIEWは非同期処理をポーリングして、処理が終了したかどうかを確認します。このポーリングはジッタに影響し、優先度の低いタスクの実行を妨げることがあります。代わりに同期処理を使用してください。同期処理は完了するまで実行され、ポーリングせずに読み取り/書き込み処理を終了できます。この違いは、「GPIB読み取り」、「GPIB書き込み」、「VISA読み取り」、「VISA書き込み」、および「VISAイベント待機」関数を使用する際に重要です。これらの関数をタイミングループまたはタイムクリティカルVI内で使用する必要がある場合は、関数を右クリックして関数を同期I/Oモードに切り替えて、ショートカットメニューから同期I/Oモード→同期を選択します。他の関数でこの構成が必要になる場合もあります。
- ネットワーク―確定的ループ内でのネットワーク操作を回避します。ネットワーク通信によって、確定的ループで制限のないジッタが発生する可能性があります。
- 制限のないアルゴリズム―アルゴリズムの中には、本質的に非確定的なものもあります。制限のないアルゴリズムを確定的ループ内で使用しないでください。VIまたは関数のジッタの性質が不明な場合は、ベンチマークを行います。
タイミングスキームを作成する
継続的な反復ループのために高精度のタイミングを確実にするには、アプリケーションで一貫したタイミングスキームを確立します。LabVIEW Real-Timeモジュールアプリケーションのタイミングスキームは、ループストラクチャとタイミングソースで構成されます。LabVIEW Real-Timeモジュールには、ループのタイミング制御に使用できる様々なタイミング方法とタイミングソースがあります。
ループを選択する
LabVIEWでは、標準的Whileループに加え、タイミング機能付きのタイミングループを使用できます。タイミングループの入力と出力を使用してアプリケーションのタイミング特性を変更、検証することができます。以下の表には、これらの2つのループストラクチャの特性が記載されています。
| ループストラクチャ | 特性 | 利点 | 欠点 |
|---|---|---|---|
| Whileループ | 基本的なループストラクチャ、マルチスレッド | 低いCPUオーバーヘッド | 標準タイミング機能なし |
| タイミングループ | マルチレートアプリケーション向けに設計されたシングルスレッドループストラクチャ | 確定的スケジューリングを促進するための標準タイミング制御、タイミングデータ、CPU選択、優先度制御、シングルスレッド | Whileループより若干高いCPUオーバーヘッド |
タイミングソースを選択する
タイミングループとWhileループのどちらを使用する場合でも、ループの反復タイミングを駆動するために、適切なタイミングソースを選択します。
Whileループタイミングソース
Whileループのタイミングを制御するには、ループ内にタイミングVIまたは関数を配置します。以下の表は、LabVIEW Real-Timeモジュールで使用できる標準タイミングVIおよび関数を示しています。
| 使用例 | タイミング方法 | 基本となるタイミングソース |
|---|---|---|
| ハードウェアタイミングI/Oを使用したループの同期 | 「DAQmx読み取り」VIやFPGA I/Oメソッドノードの待機メソッドなどのハードウェアタイミングI/Oメソッド | 外部 (ハードウェアプラットフォームに依存) |
| ループ実行をxミリ秒遅延 | 待機 | CPU駆動ミリ秒またはマイクロ秒タイマ |
| ループの実行レートの制御とループの同期 | 次の倍数まで待機 | CPU駆動ミリ秒またはマイクロ秒タイマ |
| NIスキャンエンジンの各スキャン後にループの実行をトリガ | スキャンエンジンに同期 | NI スキャンエンジン |
タイミングループタイミングソース
タイミングループのタイミングソースの選択方法の詳細については、「タイミングストラクチャのタイミングソースを選択する」のトピックを参照してください。
タイムバジェットを作成する
不要なタイミング動作を防止するには、アプリケーションのタイムバジェットを作成します。タイムバジェットの作成作業では、アプリケーション内の各ループの実行に必要な時間の決定と、それに応じたループのレートの設定を行います。タイムバジェットを作成してそれに従うことで、アプリケーションを確実に意図したとおりに実行することができます。
ループの実行時間を測定する
アプリケーションを複数のループに分割したら、RTベンチマークテクニックを使用してアプリケーション内の各ループの実行時間を確認します。ベンチマークは数千回実行し、最長の実行時間をループの実行時間として記録します。
タイムバジェット表を作成する
ループの実行時間の測定後は、以下の例のように、各ループの実行時間と周期を記録してアプリケーションのタイムバジェット表を作成します。
| タスク/ループ | 実行時間 (µS) | 周期 (µS) |
|---|---|---|
| 制御 | 400 | 1000 |
| 監視 | 3,000 | 10000 |
| ログ | 16,000 | 30000 |
低CPU使用率を維持する
100%を大幅に下回る値をCPU使用率の目標値にすると、ジッタが最小限に抑えられ、アプリケーションのタスクがCPU時間を取り合う状態を防ぐことができます。タイムバジェット表が完成すると、以下の式によってアプリケーションの理論的CPU使用率を計算できます。
CPU使用率 (%) = 100 * Sum[ループ1, ループ2,.., ループn ] (実行時間/周期)
この例の表の数値をこの式に当てはめると、CPU使用率は100 * (400/1,000 + 3,000/10,000 + 16,000/30,000) = 123%となります。この例では、監視ループの優先度がログループよりも高く設定されているため、RTOSは監視タスクを制御ループの反復終了後すぐに実行するようスケジューリングします。RTOSは、ログループが指定された周期に間に合うよう十分な時間を確保するために、必ず監視ループの反復が完了してからログループをスケジューリングします。
この場合、各ループが指定されたレートで実行されるように、1つまたは複数のループの周期を増やすことができます。たとえば、監視ループの周期を25,000 μSに、またログループの周期を80,000 μSに増やすと、理論的CPU使用率は100 * (400/1,000 + 3,000/25,000 + 16,000/80,000) = 72%となります。