問題
.Net 4.5を使用してWindows 7 ベースの C# WPFアプリケーションを作成しています。その主な機能の 1 つは、一連のユーザー定義のサイクル時間でカスタム ハードウェアとやり取りする特定の関数を呼び出すことです。たとえば、ユーザーは 2 つの関数を 10 または 20 ミリ秒ごとに呼び出し、別の関数を 500 ミリ秒ごとに呼び出すように選択できます。ユーザーが選択できる最小のサイクル時間は 1 ミリ秒です。
最初は、タイミングが正確で、必要に応じて 1 ミリ秒ごとに関数が呼び出されたように見えました。しかし、後で、約1 ~ 2%のタイミングが正確ではないことに気付きました。一部の関数はわずか 5 ミリ秒遅れて呼び出され、他の関数は最大 100 ミリ秒遅れて呼び出されました。サイクル タイムが 1 ミリ秒を超えていても、外部関数を呼び出すべき時間にスレッドがスリープするという問題に直面しました (スレッドがスリープ状態で関数を呼び出さなかったために、20 ミリ秒の関数が 50 ミリ秒遅れて呼び出される可能性があります)。
分析の結果、これらの遅延は散発的であり、目立ったパターンはなく、これらの遅延の背後にある主な原因は OS のスケジューリングとスレッド コンテキストの切り替えであると結論付けました。 .
Windows 7 は RTOS ではないため、この問題を回避できるかどうかを調べる必要があります。ただし、最大 0.7 ミリ秒のエラー許容範囲でタイミング制約を満たすことができる同様の機能を持つ他のツールを使用しているため、この問題が Windows で修正可能であることは確かです。
私たちのアプリケーションはマルチスレッド化されており、同時に最大約 30 のスレッドが実行されています。現在のピーク CPU 使用率は約 13% です。
試みられた解決策
さまざまなことを試しましたが、タイミングは主にストップウォッチ タイマーを使用して測定され、IsHighResolutionは true でした (他のタイマーが使用されましたが、大きな違いはわかりませんでした)。
別のスレッドを作成し、
それに高い優先度を与えるThread.Sleep()
C# タスク (スレッド プール) を使用する
結果:ほとんど改善されない1 ミリ秒の周期性を持つマルチメディア タイマーを使用する
結果:効果がないか、さらに悪いことに、マルチメディア タイマーは OS を起動する際には正確ですが、OS は別のスレッドを実行することを選択する可能性があり、1 ミリ秒の保証はありませんが、それでも遅延が時折大きくなる可能性がありますwhile ループとストップウォッチ タイマーだけを含む別のスタンドアロン C# プロジェクトを作成しました
。ポイント 4 を繰り返しましたが、プロセスの優先度を Realtime/High に設定し
ました。
結論:
前回から、5 つの可能な行動方針があることがわかりましたが、正しい方向に向けるためには、そのような問題の経験を持つ知識のある人が必要です。
ツールを最適化し、スレッドを何らかの方法で管理して、1 ミリ秒のリアルタイム要件を保証することができます。最適化の一部として、ツールのプロセス優先度を高またはリアルタイムに設定している可能性がありますが、ユーザーが他のいくつかのツールを同時に使用している可能性があるため、これは賢明な決定とは思えません。
ツールを 2 つのプロセスに分割します。1 つは GUI とすべての非タイム クリティカルな操作を含み、もう 1 つは最小限のタイム クリティカルな操作を含み、高/リアルタイム優先度に設定し、IPC (WCF など) を使用してプロセス間の通信。これは2つの点で私たちに利益をもたらす可能性があります
操作がはるかに少ないため、他のプロセスが枯渇する可能性が低くなります。
プロセスのスレッドが少ないため、スレッドがスリープする可能性が (はるかに低いか、まったくない)
注: 次の 2 つのポイントでは、カーネル スペースについて説明します。カーネル スペースとドライバーの作成に関する情報はほとんどないため、カーネル スペースの使用方法について間違った仮定をしている可能性があることに注意してください。
1 ミリ秒ごとに低レベルの割り込みを使用して、スレッドがプロセス内で指定されたタスクを強制的に実行するイベントを発生させるドライバーをカーネル空間に作成します。
タイム クリティカルなコンポーネントをカーネル スペースに移動し、プログラムの本体とのインターフェイスは、API とコールバックを介して行うことができます。
おそらくこれらはすべて有効ではなく、IntervalZero RTOS プラットフォームのような Windows RTOS 拡張機能を使用する必要があるのでしょうか?
質問自体
私が探している答えは 2 つあります。良い情報源に裏付けられていることを願っています。
これは本当にスレッドとコンテキストの切り替えの問題ですか? それとも、ずっと何かを見逃していたのでしょうか?
この問題を確実に解決できる 5 つのオプションはどれですか。これらのオプションのどれもそれを修正できない場合、何ができるでしょうか? 私たちがベンチマークした他のツールは、実際に Windows で必要なタイミング精度に達していることを覚えておいてください。CPU の負荷が高い場合、100,000 のうち 1 つまたは 2 つのタイミングが 2 ミリ秒未満ずれている可能性がありますが、これは非常に許容範囲です。