web-dev-qa-db-ja.com

C#のソフトリアルタイムコードに対してどのような最適化を行うことができますか?

C#でソフトリアルタイムアプリケーションを作成しています。ネットワークからのハードウェア要求への応答などの特定のタスクは、特定のミリ秒以内に完了する必要があります。ただし、そうすることは100%ミッションクリティカルではありません(つまり、ほとんどの場合は時間どおりにそれを許容でき、1%は望ましくありませんが失敗ではありません)。したがって、「ソフト」な部分です。

C#はマネージ言語であり、マネージ言語はリアルタイムアプリケーションに特に適していません。ただし、C#で物事を成し遂げる速度と、リフレクションやメモリ管理などの言語機能により、このアプリケーションを構築する作業がはるかに簡単になります。

オーバーヘッドの量を減らして確定性を高めるために実行できる最適化または設計戦略はありますか?理想的には私は次の目標を持っています

  • 「安全」になるまでガベージコレクションを遅らせる
  • ガベージコレクターがリアルタイムプロセスに干渉することなく動作できるようにする
  • さまざまなタスクのスレッド/プロセスの優先順位

C#でこれらを行う方法はありますか、C#を使用するときにリアルタイムに関して他に注意する点はありますか?

アプリケーションのプラットフォームターゲットは、Windows 7 64ビットの.NET 4.0クライアントプロファイルです。現在はクライアントプロファイルに設定していますが、これはデフォルトのオプションであり、特別な理由で選択されませんでした。

8
9a3eedi

最初の2つの箇条書きを満たす最適化は Object Pool と呼ばれます。それは

  1. プログラムの開始時にオブジェクトのプールを作成し、
  2. それらのオブジェクトへの参照をリストに維持して、ガベージコレクションが行われないようにします。
  3. 必要に応じて、プールからプログラムにオブジェクトを渡す。
  4. オブジェクトの使用が終わったら、オブジェクトをプールに戻します。

ConcurrentBaghere を使用して、オブジェクトプールを実装するクラスの例を見つけることができます。

スレッド/プロセスの優先順位は、実行時に簡単に設定できます。 スレッドクラス には、優先度とプロセッサアフィニティを設定できるメソッドとプロパティがあります。 Process Class には同様の機能が含まれています。

7
Robert Harvey

「安全」になるまでガベージコレクションを遅らせる

GCレイテンシモードLowLatencyに設定することで、これを行うことができます。詳しい情報については、 このSOに対する回答 を参照してください。

3
svick

管理された環境でゲーム開発が行うのと同じアプローチを取り、オブジェクトの作成/死を最小限に抑えるようにしてください。

例えば開始時に必要になる可能性が高いすべてのオブジェクトを作成し、強引にプールし、可能な限り参照を渡し、短期的な中間オブジェクトを作成する操作を回避する

2
lzcd

ターゲット環境(Windows)はプリエンプティブなマルチタスクO/Sであることを覚えておいてください。言い換えると、ソフトリアルタイムプロセスは、いつか別の時点で必ず回避され、.NETガベージコレクション以外のレイテンシが発生します。タイムスライス(量子)の値を減らし(デフォルトは16ミリ秒など)、プロセスの優先度を上げることで軽減できます(ただし、実際的な制限はあります)が、他の重要なプロセスがまだ必要であるため、横取りが発生する/発生します。何かをする。これはすべてプログラミング言語とは関係ありません。 O/Sの基本です。

GCの問題は別として、標準のWindowsマシンで実行されているアプリケーションは、おそらく数ミリ秒のレイテンシを提供できます。それは確かに100%の確率で保証されているわけではありません。チューニング(短いクォンタム、高い優先度)を使用しても、時折高いレイテンシが発生します。それは獣の性質です。

結論:応答時間を保証する必要がある場合、特に数ミリ秒程度の場合、Windowsはおそらく配信O/Sに最適ではありません。

0
Zenilogix