private static async Task <Tuple <bool, long, int> > Benchmark <TActor>(int factor, int numberOfClients, long numberOfRepeats, PrintStats printStats, long bestThroughput, int redCount) where TActor : ActorBase { var totalMessagesReceived = GetTotalMessagesReceived(numberOfRepeats); //times 2 since the client and the destination both send messages long repeatsPerClient = numberOfRepeats / numberOfClients; var totalWatch = Stopwatch.StartNew(); var system = ActorSystem.Create("PingPong", ConfigurationFactory.ParseString("akka.loglevel = ERROR")); var countdown = new CountdownEvent(numberOfClients * 2); var waitForStartsActor = system.ActorOf(Props.Create(() => new WaitForStarts(countdown)), "wait-for-starts"); var clients = new List <ActorRef>(); var tasks = new List <Task>(); var started = new Messages.Started(); for (int i = 0; i < numberOfClients; i++) { var destination = (LocalActorRef)system.ActorOf <Destination>("destination-" + i); destination.Cell.Dispatcher.Throughput = factor; var ts = new TaskCompletionSource <bool>(); tasks.Add(ts.Task); var client = (LocalActorRef)system.ActorOf(new Props(typeof(TActor), null, destination, repeatsPerClient, ts), "client-" + i); client.Cell.Dispatcher.Throughput = factor; clients.Add(client); client.Tell(started, waitForStartsActor); destination.Tell(started, waitForStartsActor); } if (!countdown.Wait(TimeSpan.FromSeconds(10))) { Console.WriteLine("The system did not start in 10 seconds. Aborting."); return(Tuple.Create(false, bestThroughput, redCount)); } var setupTime = totalWatch.Elapsed; var sw = Stopwatch.StartNew(); var run = new Messages.Run(); clients.ForEach(c => c.Tell(run)); await Task.WhenAll(tasks.ToArray()); sw.Stop(); system.Shutdown(); totalWatch.Stop(); var elapsedMilliseconds = sw.ElapsedMilliseconds; long throughput = elapsedMilliseconds == 0 ? -1 : totalMessagesReceived / elapsedMilliseconds * 1000; var foregroundColor = Console.ForegroundColor; if (throughput >= bestThroughput) { Console.ForegroundColor = ConsoleColor.Green; bestThroughput = throughput; redCount = 0; } else { redCount++; Console.ForegroundColor = ConsoleColor.Red; } if (printStats.HasFlag(PrintStats.StartTimeOnly)) { Console.Write("{0,5}", setupTime.TotalMilliseconds.ToString("F2", CultureInfo.InvariantCulture)); } else { if (printStats.HasFlag(PrintStats.LineStart)) { Console.Write("{0,7}, ", factor); } if (printStats.HasFlag(PrintStats.Stats)) { Console.Write("{0,8}, {1,10}, {2,10}", throughput, setupTime.TotalMilliseconds.ToString("F2", CultureInfo.InvariantCulture), totalWatch.Elapsed.TotalMilliseconds.ToString("F2", CultureInfo.InvariantCulture)); } } Console.ForegroundColor = foregroundColor; return(Tuple.Create(redCount <= 3, bestThroughput, redCount)); }
private static async Task <Tuple <bool, long, int> > Benchmark(int factor, int numberOfClients, long numberOfRepeats, PrintStats printStats, long bestThroughput, int redCount, Func <int, WaitForStarts, Tuple <IActorServerProxy, Destination> > createDestination, Func <int, Destination, IDestination> createDestClient, Func <int, WaitForStarts, IDestination, long, TaskCompletionSource <bool>, PingPongActor> createPingPong) { var totalMessagesReceived = GetTotalMessagesReceived(numberOfRepeats); //times 2 since the client and the destination both send messages long repeatsPerClient = numberOfRepeats / numberOfClients; var totalWatch = Stopwatch.StartNew(); var countdown = new CountdownEvent(numberOfClients * 2); var waitForStartsActor = new WaitForStarts(countdown); var clients = new List <PingPongActor>(); var dests = new List <Tuple <IActorServerProxy, Destination> >(); var tasks = new List <Task>(); for (int i = 0; i < numberOfClients; i++) { var destination = createDestination(i, waitForStartsActor); dests.Add(destination); var ts = new TaskCompletionSource <bool>(); tasks.Add(ts.Task); var client = createPingPong(i, waitForStartsActor, createDestClient(i, destination.Item2), repeatsPerClient, ts); clients.Add(client); client.Start(); destination.Item2.Start(); } if (!countdown.Wait(TimeSpan.FromSeconds(10))) { Console.WriteLine("The system did not start in 10 seconds. Aborting."); return(Tuple.Create(false, bestThroughput, redCount)); } var setupTime = totalWatch.Elapsed; var sw = Stopwatch.StartNew(); clients.ForEach(c => c.Ping()); await Task.WhenAll(tasks.ToArray()); sw.Stop(); totalWatch.Stop(); dests.ForEach(d => { if (d.Item1 != null) { d.Item1.Stop(); } }); dests.ForEach(d => { d.Item2.Stop(); }); clients.ForEach(c => c.Stop()); var elapsedMilliseconds = sw.ElapsedMilliseconds; long throughput = elapsedMilliseconds == 0 ? -1 : totalMessagesReceived / elapsedMilliseconds * 1000; var foregroundColor = Console.ForegroundColor; if (throughput >= bestThroughput) { Console.ForegroundColor = ConsoleColor.Green; bestThroughput = throughput; redCount = 0; } else { redCount++; Console.ForegroundColor = ConsoleColor.Red; } if (printStats.HasFlag(PrintStats.StartTimeOnly)) { Console.Write("{0,5}", setupTime.TotalMilliseconds.ToString("F2", CultureInfo.InvariantCulture)); } else { if (printStats.HasFlag(PrintStats.LineStart)) { Console.Write("{0,10}, ", factor); } if (printStats.HasFlag(PrintStats.Stats)) { Console.Write("{0,8}, {1,10}, {2,10}", throughput, setupTime.TotalMilliseconds.ToString("F2", CultureInfo.InvariantCulture), totalWatch.Elapsed.TotalMilliseconds.ToString("F2", CultureInfo.InvariantCulture)); } } Console.ForegroundColor = foregroundColor; return(Tuple.Create(redCount <= 3, bestThroughput, redCount)); }
private static async Task<Tuple<bool, long, int>> Benchmark(int factor, int numberOfClients, long numberOfRepeats, PrintStats printStats, long bestThroughput, int redCount, Func<int, WaitForStarts, Tuple<IActorServerProxy, Destination>> createDestination, Func<int, Destination, IDestination> createDestClient, Func<int, WaitForStarts, IDestination, long, TaskCompletionSource<bool>, PingPongActor> createPingPong) { var totalMessagesReceived = GetTotalMessagesReceived(numberOfRepeats); //times 2 since the client and the destination both send messages long repeatsPerClient = numberOfRepeats / numberOfClients; var totalWatch = Stopwatch.StartNew(); var countdown = new CountdownEvent(numberOfClients * 2); var waitForStartsActor = new WaitForStarts(countdown); var clients = new List<PingPongActor>(); var dests = new List<Tuple<IActorServerProxy, Destination>>(); var tasks = new List<Task>(); for (int i = 0; i < numberOfClients; i++) { var destination = createDestination(i, waitForStartsActor); dests.Add(destination); var ts = new TaskCompletionSource<bool>(); tasks.Add(ts.Task); var client = createPingPong(i, waitForStartsActor, createDestClient(i, destination.Item2), repeatsPerClient, ts); clients.Add(client); client.Start(); destination.Item2.Start(); } if (!countdown.Wait(TimeSpan.FromSeconds(10))) { Console.WriteLine("The system did not start in 10 seconds. Aborting."); return Tuple.Create(false, bestThroughput, redCount); } var setupTime = totalWatch.Elapsed; var sw = Stopwatch.StartNew(); clients.ForEach(c => c.Ping()); await Task.WhenAll(tasks.ToArray()); sw.Stop(); totalWatch.Stop(); dests.ForEach(d => { if (d.Item1 != null) d.Item1.Stop(); }); dests.ForEach(d => { d.Item2.Stop(); }); clients.ForEach(c => c.Stop()); var elapsedMilliseconds = sw.ElapsedMilliseconds; long throughput = elapsedMilliseconds == 0 ? -1 : totalMessagesReceived / elapsedMilliseconds * 1000; var foregroundColor = Console.ForegroundColor; if (throughput >= bestThroughput) { Console.ForegroundColor = ConsoleColor.Green; bestThroughput = throughput; redCount = 0; } else { redCount++; Console.ForegroundColor = ConsoleColor.Red; } if (printStats.HasFlag(PrintStats.StartTimeOnly)) { Console.Write("{0,5}", setupTime.TotalMilliseconds.ToString("F2", CultureInfo.InvariantCulture)); } else { if (printStats.HasFlag(PrintStats.LineStart)) Console.Write("{0,10}, ", factor); if (printStats.HasFlag(PrintStats.Stats)) Console.Write("{0,8}, {1,10}, {2,10}", throughput, setupTime.TotalMilliseconds.ToString("F2", CultureInfo.InvariantCulture), totalWatch.Elapsed.TotalMilliseconds.ToString("F2", CultureInfo.InvariantCulture)); } Console.ForegroundColor = foregroundColor; return Tuple.Create(redCount <= 3, bestThroughput, redCount); }
private static async Task <BenchmarkResult> Benchmark(int throughput, int numberOfClients, long numberOfRepeats, PrintStats printStats, long bestThroughput, int redCount, long repeat) { var totalMessagesReceived = GetTotalMessagesReceived(numberOfRepeats); //times 2 since the client and the destination both send messages var repeatsPerClient = numberOfRepeats / numberOfClients; var totalWatch = Stopwatch.StartNew(); var countdown = new CountdownEvent(numberOfClients * 2); var waitForStartsActorProps = Actor.FromProducer(() => new WaitForStarts(countdown)); var waitForStartsActor = Actor.SpawnNamed(waitForStartsActorProps, $"wait-for-starts-{throughput}-{repeat}"); var clients = new List <PID>(); var destinations = new List <PID>(); var tasks = new List <Task>(); var started = new Messages.Started { Sender = waitForStartsActor }; var d = new ThreadPoolDispatcher { Throughput = throughput }; for (var i = 0; i < numberOfClients; i++) { var destinationProps = Actor.FromProducer(() => new Destination()).WithDispatcher(d); var destination = Actor.SpawnNamed(destinationProps, $"destination-{i}-{throughput}-{repeat}"); destinations.Add(destination); var ts = new TaskCompletionSource <bool>(); tasks.Add(ts.Task); var clientProps = Actor.FromProducer(() => new ClientActor(destination, repeatsPerClient, ts)).WithDispatcher(d); var client = Actor.SpawnNamed(clientProps, $"client-{i}-{throughput}-{repeat}"); clients.Add(client); client.Tell(started); destination.Tell(started); } if (!countdown.Wait(TimeSpan.FromSeconds(10))) { Console.WriteLine("The system did not start in 10 seconds. Aborting."); return(new BenchmarkResult { BestThroughput = bestThroughput, RedCount = redCount }); } var setupTime = totalWatch.Elapsed; var sw = Stopwatch.StartNew(); clients.ForEach(c => { var run = new Messages.Run { Sender = c }; c.Tell(run); }); await Task.WhenAll(tasks.ToArray()); sw.Stop(); totalWatch.Stop(); var elapsedMilliseconds = sw.ElapsedMilliseconds; var throughputResult = elapsedMilliseconds == 0 ? -1 : totalMessagesReceived / elapsedMilliseconds * 1000; var foregroundColor = Console.ForegroundColor; if (throughputResult >= bestThroughput) { Console.ForegroundColor = ConsoleColor.Green; bestThroughput = throughputResult; redCount = 0; } else { redCount++; Console.ForegroundColor = ConsoleColor.Red; } if (printStats.HasFlag(PrintStats.StartTimeOnly)) { Console.Write("{0,5}", setupTime.TotalMilliseconds.ToString("F2", CultureInfo.InvariantCulture)); } else { if (printStats.HasFlag(PrintStats.LineStart)) { Console.Write("{0,10}, ", throughput); } if (printStats.HasFlag(PrintStats.Stats)) { Console.Write("{0,8}, {1,10}, {2,10}", throughputResult, setupTime.TotalMilliseconds.ToString("F2", CultureInfo.InvariantCulture), totalWatch.Elapsed.TotalMilliseconds.ToString("F2", CultureInfo.InvariantCulture)); } } Console.ForegroundColor = foregroundColor; return(new BenchmarkResult { BestThroughput = bestThroughput, RedCount = redCount }); }