static void Benchmark <T>() where T : struct { Contract.Requires(BenchmarkOptions.ContainsKey("Category")); Contract.Requires(BenchmarkOptions.ContainsKey("Operation")); Contract.Requires(BenchmarkOptions.ContainsKey("Sizes")); IConfig config = ManualConfig .Create(DefaultConfig.Instance); try { switch ((Category)BenchmarkOptions["Category"]) { case Category.MALLOC: MallocVsArrayBenchmark <T> .BenchmarkParameters = (IEnumerable <int>)BenchmarkOptions["Sizes"]; switch ((Operation)BenchmarkOptions["Operation"]) { case Operation.CREATE: config = config.With(new NameFilter(name => name.Contains("Create"))); L.Information("Starting {num} create benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, int> .GetBenchmarkMethodCount <MallocVsArrayBenchmark <T> >(), typeof(T).Name, MallocVsArrayBenchmark <T> .BenchmarkParameters); L.Information("Please allow some time for the pilot and warmup phases of the benchmark."); break; case Operation.FILL: config = config.With(new NameFilter(name => name.Contains("Fill"))); L.Information("Starting {num} fill benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, int> .GetBenchmarkMethodCount <MallocVsArrayBenchmark <T> >(), typeof(T).Name, MallocVsArrayBenchmark <T> .BenchmarkParameters); L.Information("Please allow some time for the pilot and warmup phases of the benchmark."); break; default: throw new InvalidOperationException($"Unknown operation: {(Operation)BenchmarkOptions["Operation"]} for category {(Category)BenchmarkOptions["Category"]}."); } BenchmarkSummary = BenchmarkRunner.Run <MallocVsArrayBenchmark <T> >(config); break; case Category.NARRAY: NativeVsManagedArrayBenchmark <T> .BenchmarkParameters = (IEnumerable <int>)BenchmarkOptions["Sizes"]; switch ((Operation)BenchmarkOptions["Operation"]) { case Operation.CREATE: L.Information("Starting {num} create array benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, int> .GetBenchmarkMethodCount <NativeVsManagedArrayBenchmark <T> >(), typeof(T).Name, NativeVsManagedArrayBenchmark <T> .BenchmarkParameters); L.Information("Please allow some time for the pilot and warmup phases of the benchmark."); config = config .With(new NameFilter(name => name.StartsWith("Create"))); break; case Operation.FILL: L.Information("Starting {num} array fill benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, int> .GetBenchmarkMethodCount <NativeVsManagedArrayBenchmark <T> >(), typeof(T).Name, NativeVsManagedArrayBenchmark <T> .BenchmarkParameters); L.Information("Please allow some time for the pilot and warmup phases of the benchmark."); config = config .With(new NameFilter(name => name.StartsWith("Fill"))); break; case Operation.MATH: L.Information("Starting {num} array math benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, int> .GetBenchmarkMethodCount <NativeVsManagedArrayBenchmark <T> >(), typeof(T).Name, NativeVsManagedArrayBenchmark <T> .BenchmarkParameters); L.Information("Please allow some time for the pilot and warmup phases of the benchmark."); config = config .With(new NameFilter(name => name.StartsWith("Arith"))); break; default: throw new InvalidOperationException($"Unknown operation: {(Operation)BenchmarkOptions["Operation"]} for category {(Category)BenchmarkOptions["Category"]}."); } BenchmarkSummary = BenchmarkRunner.Run <NativeVsManagedArrayBenchmark <T> >(config); break; case Category.HUGEARRAY: HugeNativeVsManagedArrayBenchmark <T> .BenchmarkParameters = (IEnumerable <ulong>)BenchmarkOptions["Sizes"]; switch ((Operation)BenchmarkOptions["Operation"]) { case Operation.CREATE: config = config.With(new NameFilter(name => name.Contains("Create"))); L.Information("Starting {num} huge array create benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, ulong> .GetBenchmarkMethodCount <HugeNativeVsManagedArrayBenchmark <T> >(), typeof(T).Name, HugeNativeVsManagedArrayBenchmark <T> .BenchmarkParameters); L.Information("This benchmark does not have a warmup phase but can still take a while (10-15 minutes.)"); break; case Operation.FILL: config = config.With(new NameFilter(name => name.Contains("Fill"))); L.Information("Starting {num} huge array fill benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, ulong> .GetBenchmarkMethodCount <HugeNativeVsManagedArrayBenchmark <T> >(), typeof(T).Name, HugeNativeVsManagedArrayBenchmark <T> .BenchmarkParameters); L.Information("This benchmark does not have a warmup phase but can still take a while (10-15 minutes.)"); break; case Operation.MATH: config = config.With(new NameFilter(name => name.Contains("Arithmetic"))); L.Information("Starting {num} huge array math benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, ulong> .GetBenchmarkMethodCount <HugeNativeVsManagedArrayBenchmark <T> >(), typeof(T).Name, HugeNativeVsManagedArrayBenchmark <T> .BenchmarkParameters); L.Information("This benchmark does not have a warmup phase but can still take a while (10-15 minutes.)"); break; default: throw new InvalidOperationException($"Unknown operation: {(Operation)BenchmarkOptions["Operation"]} for category {(Category)BenchmarkOptions["Category"]}."); } BenchmarkSummary = BenchmarkRunner.Run <HugeNativeVsManagedArrayBenchmark <T> >(config); break; default: throw new InvalidOperationException($"Unknown category: {(Category)BenchmarkOptions["Category"]}."); } } catch (Exception e) { Log.Error(e, "Exception thrown during benchmark."); Exit(ExitResult.UNHANDLED_EXCEPTION); } }
static void Benchmark <T>() where T : struct, IEquatable <T>, IComparable <T>, IConvertible { Contract.Requires(BenchmarkOptions.ContainsKey("Category")); Contract.Requires(BenchmarkOptions.ContainsKey("Operation")); Contract.Requires(BenchmarkOptions.ContainsKey("Sizes")); IConfig config = ManualConfig .Create(DefaultConfig.Instance); JemBenchmarkAttribute.CurrentConfig = config; JemBenchmarkAttribute.Category = (Category)BenchmarkOptions["Category"]; JemBenchmarkAttribute.Operation = (Operation)BenchmarkOptions["Operation"]; try { switch ((Category)BenchmarkOptions["Category"]) { case Category.MALLOC: MallocVsArrayBenchmark <T> .Debug = (bool)BenchmarkOptions["Debug"]; MallocVsArrayBenchmark <T> .Category = JemBenchmarkAttribute.Category; MallocVsArrayBenchmark <T> .Operation = JemBenchmarkAttribute.Operation; MallocVsArrayBenchmark <T> .BenchmarkParameters = ((IEnumerable <int>)BenchmarkOptions["Sizes"]).ToList(); switch ((Operation)BenchmarkOptions["Operation"]) { case Operation.CREATE: config = config.With(new NameFilter(name => name.Contains("Create"))); L.Information("Starting {num} create benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, int> .GetBenchmarkMethodCount <MallocVsArrayBenchmark <T> >(), typeof(T).Name, MallocVsArrayBenchmark <T> .BenchmarkParameters); L.Information("Please allow some time for the pilot and warmup phases of the benchmark."); break; case Operation.FILL: config = config.With(new NameFilter(name => name.Contains("Fill"))); L.Information("Starting {num} fill benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, int> .GetBenchmarkMethodCount <MallocVsArrayBenchmark <T> >(), typeof(T).Name, MallocVsArrayBenchmark <T> .BenchmarkParameters); L.Information("Please allow some time for the pilot and warmup phases of the benchmark."); break; case Operation.FRAGMENT: config = config.With(new NameFilter(name => name.Contains("Fragment"))); L.Information("Starting {num} fragment benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, int> .GetBenchmarkMethodCount <MallocVsArrayBenchmark <T> >(), typeof(T).Name, MallocVsArrayBenchmark <T> .BenchmarkParameters); L.Information("Please allow some time for the pilot and warmup phases of the benchmark."); break; default: throw new InvalidOperationException($"Unknown operation: {(Operation)BenchmarkOptions["Operation"]} for category {(Category)BenchmarkOptions["Category"]}."); } BenchmarkSummary = BenchmarkRunner.Run <MallocVsArrayBenchmark <T> >(config); break; case Category.BUFFER: FixedBufferVsManagedArrayBenchmark <T> .BenchmarkParameters = ((IEnumerable <int>)BenchmarkOptions["Sizes"]).ToList(); FixedBufferVsManagedArrayBenchmark <T> .Debug = (bool)BenchmarkOptions["Debug"]; FixedBufferVsManagedArrayBenchmark <T> .Category = JemBenchmarkAttribute.Category; FixedBufferVsManagedArrayBenchmark <T> .Operation = JemBenchmarkAttribute.Operation; switch ((Operation)BenchmarkOptions["Operation"]) { case Operation.CREATE: L.Information("Starting {num} create array benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, int> .GetBenchmarkMethodCount <FixedBufferVsManagedArrayBenchmark <T> >(), typeof(T).Name, FixedBufferVsManagedArrayBenchmark <T> .BenchmarkParameters); L.Information("Please allow some time for the pilot and warmup phases of the benchmark."); config = config .With(new NameFilter(name => name.StartsWith("Create"))); break; case Operation.FILL: L.Information("Starting {num} array fill benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, int> .GetBenchmarkMethodCount <FixedBufferVsManagedArrayBenchmark <T> >(), typeof(T).Name, FixedBufferVsManagedArrayBenchmark <T> .BenchmarkParameters); L.Information("Please allow some time for the pilot and warmup phases of the benchmark."); config = config .With(new NameFilter(name => name.StartsWith("Fill"))); break; case Operation.MATH: L.Information("Starting {num} array math benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, int> .GetBenchmarkMethodCount <FixedBufferVsManagedArrayBenchmark <T> >(), typeof(T).Name, FixedBufferVsManagedArrayBenchmark <T> .BenchmarkParameters); L.Information("Please allow some time for the pilot and warmup phases of the benchmark."); config = config .With(new NameFilter(name => name.StartsWith("Arith"))); break; default: throw new InvalidOperationException($"Unknown operation: {(Operation)BenchmarkOptions["Operation"]} for category {(Category)BenchmarkOptions["Category"]}."); } BenchmarkSummary = BenchmarkRunner.Run <FixedBufferVsManagedArrayBenchmark <T> >(config); break; case Category.NARRAY: SafeVsManagedArrayBenchmark <T> .BenchmarkParameters = ((IEnumerable <int>)BenchmarkOptions["Sizes"]).ToList(); SafeVsManagedArrayBenchmark <T> .Debug = (bool)BenchmarkOptions["Debug"]; SafeVsManagedArrayBenchmark <T> .Category = JemBenchmarkAttribute.Category; SafeVsManagedArrayBenchmark <T> .Operation = JemBenchmarkAttribute.Operation; switch ((Operation)BenchmarkOptions["Operation"]) { case Operation.CREATE: L.Information("Starting {num} create array benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, int> .GetBenchmarkMethodCount <SafeVsManagedArrayBenchmark <T> >(), typeof(T).Name, SafeVsManagedArrayBenchmark <T> .BenchmarkParameters); L.Information("Please allow some time for the pilot and warmup phases of the benchmark."); config = config .With(new NameFilter(name => name.StartsWith("Create"))); break; case Operation.FILL: L.Information("Starting {num} array fill benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, int> .GetBenchmarkMethodCount <SafeVsManagedArrayBenchmark <T> >(), typeof(T).Name, SafeVsManagedArrayBenchmark <T> .BenchmarkParameters); L.Information("Please allow some time for the pilot and warmup phases of the benchmark."); config = config .With(new NameFilter(name => name.StartsWith("Fill"))); break; case Operation.MATH: L.Information("Starting {num} array math benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, int> .GetBenchmarkMethodCount <SafeVsManagedArrayBenchmark <T> >(), typeof(T).Name, SafeVsManagedArrayBenchmark <T> .BenchmarkParameters); L.Information("Please allow some time for the pilot and warmup phases of the benchmark."); config = config .With(new NameFilter(name => name.StartsWith("Arith"))); break; default: throw new InvalidOperationException($"Unknown operation: {(Operation)BenchmarkOptions["Operation"]} for category {(Category)BenchmarkOptions["Category"]}."); } BenchmarkSummary = BenchmarkRunner.Run <SafeVsManagedArrayBenchmark <T> >(config); break; case Category.HUGEARRAY: HugeNativeVsManagedArrayBenchmark <T> .BenchmarkParameters = ((IEnumerable <ulong>)BenchmarkOptions["Sizes"]).ToList(); HugeNativeVsManagedArrayBenchmark <T> .Debug = (bool)BenchmarkOptions["Debug"]; HugeNativeVsManagedArrayBenchmark <T> .Category = JemBenchmarkAttribute.Category; HugeNativeVsManagedArrayBenchmark <T> .Operation = JemBenchmarkAttribute.Operation; switch ((Operation)BenchmarkOptions["Operation"]) { case Operation.CREATE: config = config.With(new NameFilter(name => name.Contains("Create"))); L.Information("Starting {num} huge array create benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, ulong> .GetBenchmarkMethodCount <HugeNativeVsManagedArrayBenchmark <T> >(), typeof(T).Name, HugeNativeVsManagedArrayBenchmark <T> .BenchmarkParameters); L.Information("This benchmark does not have a warmup phase but can still take a while (10-15 minutes.)"); break; case Operation.FILL: config = config.With(new NameFilter(name => name.Contains("Fill"))); L.Information("Starting {num} huge array fill benchmarks for data type {t} with array sizes: {s}", JemBenchmark <T, ulong> .GetBenchmarkMethodCount <HugeNativeVsManagedArrayBenchmark <T> >(), typeof(T).Name, HugeNativeVsManagedArrayBenchmark <T> .BenchmarkParameters); L.Information("This benchmark does not have a warmup phase but can still take a while (10-15 minutes.)"); break; default: throw new InvalidOperationException($"Unknown operation: {(Operation)BenchmarkOptions["Operation"]} for category {(Category)BenchmarkOptions["Category"]}."); } BenchmarkSummary = BenchmarkRunner.Run <HugeNativeVsManagedArrayBenchmark <T> >(config); break; case Category.VECTOR: VectorBenchmark <T> .BenchmarkParameters = ((IEnumerable <int>)BenchmarkOptions["Scales"]).ToList(); VectorBenchmark <T> .Debug = (bool)BenchmarkOptions["Debug"]; VectorBenchmark <T> .Category = JemBenchmarkAttribute.Category; VectorBenchmark <T> .Operation = JemBenchmarkAttribute.Operation; switch ((Operation)BenchmarkOptions["Operation"]) { case Operation.MANDELBROT: config = config.With(BenchmarkStatisticColumn.ThreadCycles); config = config.With(BenchmarkStatisticColumn.ISPCResult); config = config.With(BenchmarkStatisticColumn.ISPCResult2); config = config.With(new NameFilter(name => name.StartsWith("Mandelbrot"))); L.Information("Starting vector Mandelbrot benchmarks with scale: {s}", VectorBenchmark <T> .BenchmarkParameters); break; case Operation.FILL: config = config.With(new NameFilter(name => name.StartsWith("Fill"))); L.Information("Starting vector fill benchmarks with array sizes: {s}", VectorBenchmark <T> .BenchmarkParameters); break; case Operation.TEST: config = config.With(new NameFilter(name => name.StartsWith("Test"))); L.Information("Starting vector logical comparison and test benchmarks with array sizes: {s}", VectorBenchmark <T> .BenchmarkParameters); break; default: throw new InvalidOperationException($"Unknown operation: {(Operation)BenchmarkOptions["Operation"]} for category {(Category)BenchmarkOptions["Category"]}."); } BenchmarkSummary = BenchmarkRunner.Run <VectorBenchmark <T> >(config); break; default: throw new InvalidOperationException($"Unknown category: {(Category)BenchmarkOptions["Category"]}."); } } catch (Exception e) { Log.Error(e, "Exception thrown during benchmark."); Exit(ExitResult.UNHANDLED_EXCEPTION); } }