diff --git a/src/CSharp/App/App.cs b/src/CSharp/App/App.cs index c4db3b9..4abffb7 100644 --- a/src/CSharp/App/App.cs +++ b/src/CSharp/App/App.cs @@ -18,21 +18,29 @@ public class Options Default = 10)] public int? Duration { get; set; } - [Option('m', "ram", Required = false, HelpText = "RAM size, GB", + [Option('m', "staticSetSize", Required = false, HelpText = "Static set size, GB", Default = null)] // null = same as physical RAM amount - public string RamSize { get; set; } + public string StaticSetSize { get; set; } [Option('t', "threads", Required = false, HelpText = "Number of threads to use", Default = null)] public string ThreadCount { get; set; } + [Option('o', "maxSize", Required = false, HelpText = "Max. object size", + Default = null)] // null = don't change what's on start + public string MaxSize { get; set; } + + [Option('r', "runTests", Required = false, HelpText = "Tests to run (a = raw allocation, b = burn)", + Default = null)] // null = don't change what's on start + public string Tests { get; set; } + [Option('l', "gcLatencyMode", Required = false, HelpText = "Latency mode", Default = null)] // null = don't change what's on start public string GCLatencyMode { get; set; } - - [Option('s', "maxSize", Required = false, HelpText = "Max. object size", + + [Option('p', "outputMode", Required = false, HelpText = "Output mode (f = full, m = minimal)", Default = null)] // null = don't change what's on start - public string MaxSize { get; set; } + public string OutputMode { get; set; } } public IndentedTextWriter Writer = new IndentedTextWriter(Console.Out, " "); @@ -63,66 +71,80 @@ public void Run(Options options) options.MaxSize, BurnTester.DefaultMaxSize, true); ParallelRunner.ThreadCount = (int) ArgumentHelper.ParseRelativeValue( options.ThreadCount, ParallelRunner.ThreadCount, true); - var hardwareRamSize = HardwareInfo.GetRamSize(); - var testedRamSize = (int) ArgumentHelper.ParseRelativeValue(options.RamSize, hardwareRamSize ?? 4, true); + var tests = options.Tests?.ToLowerInvariant() ?? ""; + var ramSizeGb = HardwareInfo.GetRamSize() ?? 4; + var staticSetSizeGb = 0; + if (!string.IsNullOrEmpty(options.StaticSetSize)) { + tests += "b"; + staticSetSizeGb = (int) ArgumentHelper.ParseRelativeValue(options.StaticSetSize, ramSizeGb, true); + } + var outputMode = options.OutputMode ?? "f"; + + if (outputMode == "f") { + // Dumping environment info + Writer.AppendValue("Launch parameters", string.Join(" ", Environment.GetCommandLineArgs().Skip(1))); + using (Writer.Section("Software:")) { + Writer.AppendValue("Runtime", ".NET Core"); + using (Writer.Indent()) { + Writer.AppendValue("Version", RuntimeInformation.FrameworkDescription); + Writer.AppendValue("GC mode", GCInfo.GetGCMode()); + } - // Dumping environment info - Writer.AppendValue("Launch parameters", string.Join(" ", Environment.GetCommandLineArgs().Skip(1))); - using (Writer.Section("Software:")) { - Writer.AppendValue("Runtime", ".NET Core"); - using (Writer.Indent()) { - Writer.AppendValue("Version", RuntimeInformation.FrameworkDescription); - Writer.AppendValue("GC mode", GCInfo.GetGCMode()); + Writer.AppendValue("OS", + $"{RuntimeInformation.OSDescription.Trim()} ({RuntimeInformation.OSArchitecture})"); } - Writer.AppendValue("OS", $"{RuntimeInformation.OSDescription.Trim()} ({RuntimeInformation.OSArchitecture})"); - } - using (Writer.Section("Hardware:")) { - var coreCountAddon = ParallelRunner.ThreadCount != Environment.ProcessorCount - ? $" (assuming {ParallelRunner.ThreadCount} during the test)" - : ""; - Writer.AppendValue("CPU", HardwareInfo.GetCpuModelName()); - Writer.AppendValue("CPU core count", $"{Environment.ProcessorCount}{coreCountAddon}"); - var ramSizeAddon = testedRamSize != hardwareRamSize - ? $" (assuming {testedRamSize} GB during the test)" - : ""; - Writer.AppendValue("RAM size", $"{hardwareRamSize.ToString("N0", "GB")}{ramSizeAddon}"); + + using (Writer.Section("Hardware:")) { + var coreCountAddon = ParallelRunner.ThreadCount != Environment.ProcessorCount + ? $", {ParallelRunner.ThreadCount} used by test" + : ""; + Writer.AppendValue("CPU", HardwareInfo.GetCpuModelName()); + Writer.AppendValue("CPU core count", $"{Environment.ProcessorCount}{coreCountAddon}"); + Writer.AppendValue("RAM size", $"{ramSizeGb:N0} GB"); + } + Writer.AppendLine(); } + + RunWarmup(); - // Checking whether we actually know the RAM size to test - var ramSize = testedRamSize * Sizes.GB; + if (tests == "") { + RunSpeedTest(); + RunBurnTest("--- Stateless server (no static set) ---", 0); + RunBurnTest("--- Worker / typical server (static set = 20% RAM) ---", (long) (ramSizeGb * Sizes.GB / 5)); + RunBurnTest("--- Caching / compute server (static set = 50% RAM) ---", (long) (ramSizeGb * Sizes.GB / 2)); + return; + } - // Finally, running the test - SpeedTester speedTester; - BurnTester burnTester; - using (Writer.Section("Warming up...")) { - speedTester = SpeedTester.NewWarmup(); - speedTester.Run(); - speedTester = null; - burnTester = BurnTester.NewWarmup(1 * (long) Sizes.GB); - burnTester.Run(); - burnTester = null; - Writer.AppendLine("Done."); + if (tests.Contains("a")) { + RunSpeedTest(); } - Writer.AppendLine(); + if (tests.Contains("b")) { + var title = $"--- Static set = {staticSetSizeGb} GB ({staticSetSizeGb * 100.0 / ramSizeGb:0.##} % RAM) ---"; + RunBurnTest(title, (long) (staticSetSizeGb * Sizes.GB)); + } + } - Writer.AppendLine("--- Raw allocation (w/o holding what's allocated) ---"); - Writer.AppendLine(); - speedTester = SpeedTester.New(); + public void RunWarmup() + { + var speedTester = SpeedTester.NewWarmup(); speedTester.Run(); - - Writer.AppendLine("--- Stateless server (no static set) ---"); - Writer.AppendLine(); - burnTester = BurnTester.New(0); + var burnTester = BurnTester.NewWarmup(10 * (long) Sizes.MB); burnTester.Run(); + } - Writer.AppendLine("--- Worker / typical server (static set = 20% RAM) ---"); + public void RunSpeedTest() + { + Writer.AppendLine("--- Raw allocation (w/o holding what's allocated) ---"); Writer.AppendLine(); - burnTester = BurnTester.New((long) (ramSize * 0.2)); - burnTester.Run(); - - Writer.AppendLine("--- Caching / compute server (static set = 50% RAM) ---"); + var speedTester = SpeedTester.New(); + speedTester.Run(); + } + + public void RunBurnTest(string title, long staticSetSize) + { + Writer.AppendLine(title); Writer.AppendLine(); - burnTester = BurnTester.New((long) (ramSize * 0.5)); + var burnTester = BurnTester.New(staticSetSize); burnTester.Run(); } } diff --git a/src/CSharp/Main/SpeedTest/SpeedTester.cs b/src/CSharp/Main/SpeedTest/SpeedTester.cs index 8e14fd3..b33a74d 100644 --- a/src/CSharp/Main/SpeedTest/SpeedTester.cs +++ b/src/CSharp/Main/SpeedTest/SpeedTester.cs @@ -9,14 +9,14 @@ namespace GCBurn.SpeedTest { public class SpeedTester { - public const int PassCount = 10; + public const int PassCount = 30; public static TimeSpan DefaultDuration = TimeSpan.FromMilliseconds(1); public TimeSpan Duration = DefaultDuration; public IndentedTextWriter Writer = new IndentedTextWriter(Console.Out, " "); public static SpeedTester New() => new SpeedTester(); public static SpeedTester NewWarmup() => new SpeedTester() { - Duration = TimeSpan.FromSeconds(1), + Duration = TimeSpan.FromMilliseconds(5), Writer = new IndentedTextWriter(TextWriter.Null), };