From 4bd433d85fff4fb6ba8c4f8df3e685ad669e2519 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Tue, 3 Aug 2021 16:38:06 +0200 Subject: [PATCH] use benchmark process runtime, not host process runtime when deciding whether allocation quantum side effects should be excluded --- .../Diagnosers/MemoryDiagnoser.cs | 2 +- src/BenchmarkDotNet/Engines/GcStats.cs | 21 ++++++++----------- .../Exporters/Csv/CsvMeasurementsExporter.cs | 2 +- src/BenchmarkDotNet/Reports/SummaryTable.cs | 2 +- .../MemoryDiagnoserTests.cs | 2 +- 5 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/BenchmarkDotNet/Diagnosers/MemoryDiagnoser.cs b/src/BenchmarkDotNet/Diagnosers/MemoryDiagnoser.cs index 078718539b..e922711b78 100644 --- a/src/BenchmarkDotNet/Diagnosers/MemoryDiagnoser.cs +++ b/src/BenchmarkDotNet/Diagnosers/MemoryDiagnoser.cs @@ -36,7 +36,7 @@ public IEnumerable ProcessResults(DiagnoserResults diagnoserResults) yield return new Metric(GarbageCollectionsMetricDescriptor.Gen0, diagnoserResults.GcStats.Gen0Collections / (double)diagnoserResults.GcStats.TotalOperations * 1000); yield return new Metric(GarbageCollectionsMetricDescriptor.Gen1, diagnoserResults.GcStats.Gen1Collections / (double)diagnoserResults.GcStats.TotalOperations * 1000); yield return new Metric(GarbageCollectionsMetricDescriptor.Gen2, diagnoserResults.GcStats.Gen2Collections / (double)diagnoserResults.GcStats.TotalOperations * 1000); - yield return new Metric(AllocatedMemoryMetricDescriptor.Instance, diagnoserResults.GcStats.BytesAllocatedPerOperation); + yield return new Metric(AllocatedMemoryMetricDescriptor.Instance, diagnoserResults.GcStats.GetBytesAllocatedPerOperation(diagnoserResults.BenchmarkCase)); } private class AllocatedMemoryMetricDescriptor : IMetricDescriptor diff --git a/src/BenchmarkDotNet/Engines/GcStats.cs b/src/BenchmarkDotNet/Engines/GcStats.cs index b30a567276..2f2552b4d0 100644 --- a/src/BenchmarkDotNet/Engines/GcStats.cs +++ b/src/BenchmarkDotNet/Engines/GcStats.cs @@ -2,6 +2,7 @@ using System.Reflection; using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Portability; +using BenchmarkDotNet.Running; using JetBrains.Annotations; namespace BenchmarkDotNet.Engines @@ -38,19 +39,15 @@ private GcStats(int gen0Collections, int gen1Collections, int gen2Collections, l public long TotalOperations { get; } - public long BytesAllocatedPerOperation + public long GetBytesAllocatedPerOperation(BenchmarkCase benchmarkCase) { - get - { - bool excludeAllocationQuantumSideEffects = !RuntimeInformation.IsNetCore - || RuntimeInformation.GetCurrentRuntime().RuntimeMoniker == RuntimeMoniker.NetCoreApp20; // the issue got fixed for .NET Core 2.0+ https://github.com/dotnet/coreclr/issues/10207 - - return GetTotalAllocatedBytes(excludeAllocationQuantumSideEffects) == 0 - ? 0 - : (long) Math.Round( // let's round it to reduce the side effects of Allocation quantum - (double) GetTotalAllocatedBytes(excludeAllocationQuantumSideEffects) / TotalOperations, - MidpointRounding.ToEven); - } + bool excludeAllocationQuantumSideEffects = benchmarkCase.GetRuntime().RuntimeMoniker <= RuntimeMoniker.NetCoreApp20; // the issue got fixed for .NET Core 2.0+ https://github.com/dotnet/coreclr/issues/10207 + + return GetTotalAllocatedBytes(excludeAllocationQuantumSideEffects) == 0 + ? 0 + : (long) Math.Round( // let's round it to reduce the side effects of Allocation quantum + (double) GetTotalAllocatedBytes(excludeAllocationQuantumSideEffects) / TotalOperations, + MidpointRounding.ToEven); } public static GcStats operator +(GcStats left, GcStats right) diff --git a/src/BenchmarkDotNet/Exporters/Csv/CsvMeasurementsExporter.cs b/src/BenchmarkDotNet/Exporters/Csv/CsvMeasurementsExporter.cs index 418b61962f..a02953fe63 100644 --- a/src/BenchmarkDotNet/Exporters/Csv/CsvMeasurementsExporter.cs +++ b/src/BenchmarkDotNet/Exporters/Csv/CsvMeasurementsExporter.cs @@ -69,7 +69,7 @@ private static MeasurementColumn[] GetColumns(Summary summary) new MeasurementColumn("Gen_0", (_, report, __) => report.GcStats.Gen0Collections.ToString(summary.GetCultureInfo())), new MeasurementColumn("Gen_1", (_, report, __) => report.GcStats.Gen1Collections.ToString(summary.GetCultureInfo())), new MeasurementColumn("Gen_2", (_, report, __) => report.GcStats.Gen2Collections.ToString(summary.GetCultureInfo())), - new MeasurementColumn("Allocated_Bytes", (_, report, __) => report.GcStats.BytesAllocatedPerOperation.ToString(summary.GetCultureInfo())) + new MeasurementColumn("Allocated_Bytes", (_, report, __) => report.GcStats.GetBytesAllocatedPerOperation(report.BenchmarkCase).ToString(summary.GetCultureInfo())) }; return columns.ToArray(); diff --git a/src/BenchmarkDotNet/Reports/SummaryTable.cs b/src/BenchmarkDotNet/Reports/SummaryTable.cs index 6e20290977..c4bca02703 100644 --- a/src/BenchmarkDotNet/Reports/SummaryTable.cs +++ b/src/BenchmarkDotNet/Reports/SummaryTable.cs @@ -50,7 +50,7 @@ internal SummaryTable(Summary summary, SummaryStyle style = null) if (style.SizeUnit == null) { - style = style.WithSizeUnit(SizeUnit.GetBestSizeUnit(summary.Reports.Select(r => r.GcStats.BytesAllocatedPerOperation).ToArray())); + style = style.WithSizeUnit(SizeUnit.GetBestSizeUnit(summary.Reports.Select(r => r.GcStats.GetBytesAllocatedPerOperation(r.BenchmarkCase)).ToArray())); } var columns = summary.GetColumns(); diff --git a/tests/BenchmarkDotNet.IntegrationTests/MemoryDiagnoserTests.cs b/tests/BenchmarkDotNet.IntegrationTests/MemoryDiagnoserTests.cs index dfb0c568b7..89af9fd4c9 100755 --- a/tests/BenchmarkDotNet.IntegrationTests/MemoryDiagnoserTests.cs +++ b/tests/BenchmarkDotNet.IntegrationTests/MemoryDiagnoserTests.cs @@ -276,7 +276,7 @@ private void AssertAllocations(IToolchain toolchain, Type benchmarkType, Diction { var benchmarkReport = summary.Reports.Single(report => report.BenchmarkCase == benchmark); - Assert.Equal(benchmarkAllocationsValidator.Value, benchmarkReport.GcStats.BytesAllocatedPerOperation); + Assert.Equal(benchmarkAllocationsValidator.Value, benchmarkReport.GcStats.GetBytesAllocatedPerOperation(benchmark)); if (benchmarkAllocationsValidator.Value == 0) {