Skip to content

Commit

Permalink
Moved stackalloc to separate method. (#2374)
Browse files Browse the repository at this point in the history
  • Loading branch information
timcassell committed Mar 25, 2024
1 parent 7306ee7 commit 4ab69be
Showing 1 changed file with 24 additions and 10 deletions.
34 changes: 24 additions & 10 deletions src/BenchmarkDotNet/Engines/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,9 @@ public Measurement RunIteration(IterationData data)
if (EngineEventSource.Log.IsEnabled())
EngineEventSource.Log.IterationStart(data.IterationMode, data.IterationStage, totalOperations);

Span<byte> stackMemory = randomizeMemory ? stackalloc byte[random.Next(32)] : Span<byte>.Empty;

// Measure
var clock = Clock.Start();
action(invokeCount / unrollFactor);
var clockSpan = clock.GetElapsed();
var clockSpan = randomizeMemory
? MeasureWithRandomMemory(action, invokeCount / unrollFactor)
: Measure(action, invokeCount / unrollFactor);

if (EngineEventSource.Log.IsEnabled())
EngineEventSource.Log.IterationStop(data.IterationMode, data.IterationStage, totalOperations);
Expand All @@ -190,9 +187,29 @@ public Measurement RunIteration(IterationData data)
if (measurement.IterationStage == IterationStage.Jitting)
jittingMeasurements.Add(measurement);

return measurement;
}

// This is in a separate method, because stackalloc can affect code alignment,
// resulting in unexpected measurements on some AMD cpus,
// even if the stackalloc branch isn't executed. (#2366)
[MethodImpl(MethodImplOptions.NoInlining)]
private unsafe ClockSpan MeasureWithRandomMemory(Action<long> action, long invokeCount)
{
byte* stackMemory = stackalloc byte[random.Next(32)];
var clockSpan = Measure(action, invokeCount);
Consume(stackMemory);
return clockSpan;
}

return measurement;
[MethodImpl(MethodImplOptions.NoInlining)]
private unsafe void Consume(byte* _) { }

private ClockSpan Measure(Action<long> action, long invokeCount)
{
var clock = Clock.Start();
action(invokeCount);
return clock.GetElapsed();
}

private (GcStats, ThreadingStats, double) GetExtraStats(IterationData data)
Expand Down Expand Up @@ -224,9 +241,6 @@ public Measurement RunIteration(IterationData data)
return (gcStats, threadingStats, exceptionsStats.ExceptionsCount / (double)totalOperationsCount);
}

[MethodImpl(MethodImplOptions.NoInlining)]
private void Consume(in Span<byte> _) { }

private void RandomizeManagedHeapMemory()
{
// invoke global cleanup before global setup
Expand Down

0 comments on commit 4ab69be

Please sign in to comment.