C#でソフトリアルタイムアプリケーションを作成しています。ネットワークからのハードウェア要求への応答などの特定のタスクは、特定のミリ秒以内に完了する必要があります。ただし、そうすることは100%ミッションクリティカルではありません(つまり、ほとんどの場合は時間どおりにそれを許容でき、1%は望ましくありませんが失敗ではありません)。したがって、「ソフト」な部分です。
C#はマネージ言語であり、マネージ言語はリアルタイムアプリケーションに特に適していません。ただし、C#で物事を成し遂げる速度と、リフレクションやメモリ管理などの言語機能により、このアプリケーションを構築する作業がはるかに簡単になります。
オーバーヘッドの量を減らして確定性を高めるために実行できる最適化または設計戦略はありますか?理想的には私は次の目標を持っています
C#でこれらを行う方法はありますか、C#を使用するときにリアルタイムに関して他に注意する点はありますか?
アプリケーションのプラットフォームターゲットは、Windows 7 64ビットの.NET 4.0クライアントプロファイルです。現在はクライアントプロファイルに設定していますが、これはデフォルトのオプションであり、特別な理由で選択されませんでした。
最初の2つの箇条書きを満たす最適化は Object Pool と呼ばれます。それは
ConcurrentBag
here を使用して、オブジェクトプールを実装するクラスの例を見つけることができます。
スレッド/プロセスの優先順位は、実行時に簡単に設定できます。 スレッドクラス には、優先度とプロセッサアフィニティを設定できるメソッドとプロパティがあります。 Process Class には同様の機能が含まれています。
「安全」になるまでガベージコレクションを遅らせる
GCレイテンシモード をLowLatency
に設定することで、これを行うことができます。詳しい情報については、 このSOに対する回答 を参照してください。
管理された環境でゲーム開発が行うのと同じアプローチを取り、オブジェクトの作成/死を最小限に抑えるようにしてください。
例えば開始時に必要になる可能性が高いすべてのオブジェクトを作成し、強引にプールし、可能な限り参照を渡し、短期的な中間オブジェクトを作成する操作を回避する
ターゲット環境(Windows)はプリエンプティブなマルチタスクO/Sであることを覚えておいてください。言い換えると、ソフトリアルタイムプロセスは、いつか別の時点で必ず回避され、.NETガベージコレクション以外のレイテンシが発生します。タイムスライス(量子)の値を減らし(デフォルトは16ミリ秒など)、プロセスの優先度を上げることで軽減できます(ただし、実際的な制限はあります)が、他の重要なプロセスがまだ必要であるため、横取りが発生する/発生します。何かをする。これはすべてプログラミング言語とは関係ありません。 O/Sの基本です。
GCの問題は別として、標準のWindowsマシンで実行されているアプリケーションは、おそらく数ミリ秒のレイテンシを提供できます。それは確かに100%の確率で保証されているわけではありません。チューニング(短いクォンタム、高い優先度)を使用しても、時折高いレイテンシが発生します。それは獣の性質です。
結論:応答時間を保証する必要がある場合、特に数ミリ秒程度の場合、Windowsはおそらく配信O/Sに最適ではありません。