次の問題を解決しようとしています。数ミリ秒の大きなハートビートでリアルタイムで実行されているエージェントがいくつかありますが、この理由でエージェントが処理する操作の順序はほとんど決定論的です (メッセージ処理がボトルネックではないため)。
現在、ハートビートがなくなったシステムの大量のシミュレーションを実行しています (そうでなければ、数世紀かかります)。ただし、操作の順序が保持されていることを確認する必要があります。このために、私は次の解決策を採用しました。シミュレーターは、ダミーの同期メッセージを投稿し、応答を待っている間にブロックすることで、各エージェントがメッセージ キューを処理したことを確認します。これは私のアプリケーションでは機能しますが、かかる時間は直感的ではありません-シングルスレッドの実装は桁違いに高速になるためです(テストしていませんが、x 100程度だと思います)。
別のライブラリ akka.net を使用しようとしても、問題を示す小さなテストを分離しました
type Greet =
| Greet of string
| Hello of AsyncReplyChannel<bool>
| Hello2
[<EntryPoint>]
let main argv =
let system = System.create "MySystem" <| Configuration.load()
let greeter = spawn system "greeter" <| fun mailbox ->
let rec loop() = actor {
let! msg = mailbox.Receive()
let sender = mailbox.Sender()
match msg with
| Greet who -> () // printf "Hello, %s!\n" who
| Hello2 -> sender.Tell(true)
| _ -> ()
return! loop()
}
loop()
let greeterF =
MailboxProcessor.Start
(fun inbox ->
async {
while true do
let! msg = inbox.Receive()
match msg with
| Greet who -> () // printf "Hello, %s!\n" who
| Hello reply -> reply.Reply true
| _ -> ()
}
)
let n = 1000000
let t1 = System.Diagnostics.Stopwatch()
t1.Start()
for i = 1 to n do
let rep = greeterF.PostAndReply(fun reply -> (Hello reply)) |> ignore
()
printfn "elapsed Mailbox:%A" t1.ElapsedMilliseconds
t1.Restart()
for i = 1 to n do
let res = greeter.Ask (Hello2)
let rr = res.Result
()
printfn "elapsed Akka:%A" t1.ElapsedMilliseconds
System.Console.ReadLine () |> ignore
0
基本的に、どちらもわずか 100 万回の同期に約 10 秒かかります。これは計算に関係なく、残念なことです。
誰かが同じ問題に遭遇したかどうか、そしてオーバーヘッドをオフにしてすべてをシングルスレッドモードで実行させる方法があるかどうか疑問に思っています...すべてのCPUを非アクティブ化するよりも優れていますが、BIOSで1つ-またはエージェントなしでシステム全体のクローンを作成します。
どんな助けでも大歓迎です。