Tmds.LinuxAsync icon indicating copy to clipboard operation
Tmds.LinuxAsync copied to clipboard

Automate benchmark execution

Open antonfirsov opened this issue 4 years ago • 1 comments

The parameter space became large and complex, running benchmarks is real chore now, and it would be even harder on Citrine, where we need to test with bigger ranges of t. To improve our productivity, I'm planning to implement some automation.

Goals:

  • Automate BenchmarkDriver(2) execution for a given set of parameters.
  • Produce output that is easy to deal with. Suggestion: .csv
    • Conversion to .md should be trivial (in case of excel: just copy paste the table to GitHub)
    • Making charts would be easy

Possible solutions:

  • A PowerShell script to control BenchmarkDriver(2) for us. Disadvantage: it's PowerShell ;)
  • A small C# app to control BenchmarkDriver(2) for us. Disadvantage: not self-contained enough, needs to be compiled

Example usage:

./RunBenchmarks.ps1 --server http://asp-perf-lin:5001 --client "http://asp-perf-load:5002" -e=epoll,uring -o=iothread,inline -t=4..8

This will run 2 * 2 * 5 = 20 benchmarks in total, and save there results in a CSV having the scheme:

e o t RPS CPU% latency
. . . .. .... ......
. . . .. .... ......
. . . .. .... ......

@adamsitnik any concerns/expectations from your side? Preference for C# vs PowerShell?

antonfirsov avatar Mar 23 '20 13:03 antonfirsov

I am a n00b and I always go 100% C# 🗡

I've written a very small app that parses commands from a file and runs the benchmarks. Everything is hardcoded, but it gives me what I want, you might find it usefull:

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace BenchmarkScheduler
{
    class Program
    {
        static void Main(string[] args)
        {
            const string workingDirectory = @"C:\Projects\aspnet_benchmarks\src\BenchmarksDriver";
            const string commandPrefix = @"run -c Release -- --display-output --server http://asp-perf-lin:5001 --client http://asp-perf-load:5002 --repository https://github.com/tmds/Tmds.LinuxAsync.git --project-file test/web/web.csproj --collect-trace";

            foreach (var commandSuffix in File.ReadAllLines(@"C:\Users\adsitnik\source\repos\BenchmarkScheduler\BenchmarkScheduler\commands.txt").Where(x => !string.IsNullOrEmpty(x)))
            {
                Console.WriteLine("```cmd");
                Console.WriteLine(commandSuffix);
                Console.WriteLine("```");

                Console.WriteLine("```log");

                using (var process = Process.Start(new ProcessStartInfo()
                {
                    FileName = "dotnet",
                    Arguments = $"{commandPrefix} {commandSuffix}",
                    WorkingDirectory = workingDirectory,
                    RedirectStandardOutput = true,
                    UseShellExecute = false,
                    CreateNoWindow = true
                }))
                {
                    string line = null;
                    while ((line = process.StandardOutput.ReadLine()) != null)
                    {
                        if (!string.IsNullOrEmpty(line) && !line.StartsWith('[') && !line.StartsWith("failed"))
                        {
                            Console.WriteLine(line);
                        }
                    }

                    if (process.HasExited)
                    {
                        process.WaitForExit();
                    }
                }

                Console.WriteLine("```");
            }
        }
    }
}

adamsitnik avatar Mar 23 '20 14:03 adamsitnik