説明
私は現在、C# マルチエージェント シミュレーション用のアーキテクチャを設計しています。このアーキテクチャでは、エージェントのアクションは、センサーを読み取ったり、アクションに投票したり、他のモジュールにメッセージやクエリを送信したりする「頭脳」内の多くのモジュールによって駆動されます (これらはすべて、メッセージの交換)。もちろん、モジュールは状態を持つことができます。
モジュールは並行して実行されます。メッセージとクエリを消費し、何らかの計算を実行する update メソッドがあります。update メソッドは反復子を返し、その本体に複数の yield があるため、モジュールを協調的にスケジュールできます。エージェントごとに数百から数千のモジュールがあると予想されるため、モジュールごとに単一のスレッドを使用しません。これにより、スレッドのオーバーヘッドによって膨大な量の RAM が占有されることになります。
これらのモジュールをランタイム プラグインのように動作させて、シミュレーションの実行中に新しいモジュール クラスを追加し、シミュレーション プロセスを停止することなく既存のクラスを書き換え/デバッグし、それらのクラスを使用してモジュールを追加および削除できるようにしたいと考えています。エージェントの頭脳、またはメソッドの新しい実装により、既存のモジュールに動作を変更させるだけです。
可能な解決策
私はここ数日でいくつかの可能な解決策を考え出しましたが、どれもがっかりしました:
モジュールを DLL にコンパイルし、それぞれを別のAppDomainにロードしてから、AppDomain.CreateInstanceFromAndUnwrap() を使用してモジュールをインスタンス化し、それをいくつかの IModule インターフェイスにキャストして、シミュレーションとモジュールの間で共有 (および各モジュール クラスによって実装) します。 . インターフェイスは、SendMessage、Update、およびすべてのモジュールに共通の他のいくつかのメンバーのみを公開します。
- このソリューションの問題は、AppDomain 間の呼び出しが (同じ AppDomain 内の) 直接呼び出しよりもはるかに遅いことです。
- また、AppDomains のオーバーヘッドはわかりませんが、無料ではないので、何千もあると問題になる可能性があります。
アセンブリのロード/アンロードがないように、モジュールにはスクリプト言語を使用し、基になるエンジンには C# を使用します。代わりに、各モジュールのスクリプト言語の実行コンテキストをホストします。
- 私の主な懸念は、大きなスクリプト言語 (「python、lua、ruby、js は大きく、Autoit と Euphoria はそうではない」など) を知らないことです。モジュール実行の協調スケジューリングを実行するために必要です)。
- これに関するもう 1 つの懸念は、モジュールごとにランタイム コンテキストを使用する必要があり、その結果、膨大なオーバーヘッドが発生することです。
- 最後に、スクリプト言語はおそらく C# よりも遅く、パフォーマンスが低下すると思います。
アセンブリのアンロードを避け、代わりに何らかの方法で名前を変更/バージョン付けして、さまざまなバージョンを多数持つことができるようにし、タイプごとに最新のものを使用します。
- これが可能かどうかさえわかりません(不愉快な型と名前空間のため)
- たとえ可能であったとしても、それは非常にメモリ効率が悪いでしょう。
透過的にシミュレーションを再開します。つまり、シミュレーション (およびブレイン/モジュールのスケジューラーの実行) を一時停止し、すべて (すべてのモジュールを含む) をシリアル化し、シミュレーションを終了し、コードを再コンパイルし、シミュレーションを再度開始し、すべてを逆シリアル化し、キャッチします。クラスに変更を加えて実行を再開したために発生した例外。
- これは大変な作業なので、最後の手段と考えています。
- また、このプロセス全体は、モジュールの数とそのサイズによっては、ある時点で非常に遅くなり、実用的ではなくなります
この最後の問題 (ソリューション 4 のプロセス全体が遅くなる) を解決するには、ソリューション 3 と 4 を混ぜ合わせ、多数のアセンブリを何らかの形式のバージョン管理で読み込み、時々再起動して混乱を解消します。それでも、モジュール クラスに小さな変更を加えたからといって、シミュレーション全体を中断しないものを好むでしょう。
実際の質問
だからここに私の質問があります:他の解決策はありますか?私が見つけた問題の回避策を見逃していませんか? たとえば、私のニーズを満たす .NET 用のスクリプト言語はありますか (解決策 #2)? 私が漠然と説明した方法でバージョン管理は可能ですか (解決策 #3)?
または、もっと簡単に言うと、.NET はこのプロジェクトのプラットフォームとして適切ではないのでしょうか? (C# がメインの言語なので、このまま使い続けたいと思っていますが、必要に応じて Python などでこれを行うことも考えられます)