我正在尝试解决以下问题。我有一些实时运行的代理,具有几毫秒的大心跳,因此它们处理的操作顺序大多是确定性的(因为消息处理不是瓶颈)。
现在,我正在对不再有心跳的系统进行大量模拟(否则将需要几个世纪)——但我需要确保操作顺序得以保留。为此,我采用了以下解决方案:模拟器确保每个代理都处理了他的消息队列,方法是发布一个虚拟同步消息并在等待答案时阻塞。这确实适用于我的应用程序,但它所花费的时间并不直观 - 因为单线程实现会快一个数量级(我猜 - x 100 ish - 虽然我没有测试过)。
我已经隔离了一个显示问题的小测试,甚至尝试使用另一个库 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 - 或在没有代理的情况下编写整个系统的克隆。
任何帮助都非常感谢。