Skip to content

AggressiveOptimization in InProcess toolchains #2335

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using BenchmarkDotNet.Portability;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
Expand Down Expand Up @@ -37,5 +38,13 @@ public static MethodBuilder SetNoOptimizationImplementationFlag(this MethodBuild

return methodBuilder;
}

public static MethodBuilder SetAggressiveOptimizationImplementationFlag(this MethodBuilder methodBuilder)
{
methodBuilder.SetImplementationFlags(
methodBuilder.GetMethodImplementationFlags() | CodeGenHelper.AggressiveOptimizationOptionForEmit);

return methodBuilder;
}
}
}
12 changes: 12 additions & 0 deletions src/BenchmarkDotNet/Portability/CodeGen.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Reflection;
using System.Runtime.CompilerServices;

namespace BenchmarkDotNet.Portability
{
public static class CodeGenHelper
{
// AggressiveOptimization is not available in netstandard2.0, so just use the value casted to enum.
public const MethodImplOptions AggressiveOptimizationOption = (MethodImplOptions) 512;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this value ignored by the older runtimes?

cc @AndyAyersMS who added the annotations with ifdefs

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I believe it will be ignored by older .NET Core and all .NET Framework versions.

public const MethodImplAttributes AggressiveOptimizationOptionForEmit = (MethodImplAttributes) 512;
}
}
80 changes: 20 additions & 60 deletions src/BenchmarkDotNet/Templates/BenchmarkType.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,7 @@

private BenchmarkDotNet.Engines.Consumer consumer = new BenchmarkDotNet.Engines.Consumer();

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void OverheadActionUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -125,9 +123,7 @@
}
}

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void OverheadActionNoUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -137,9 +133,7 @@
}
}

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void WorkloadActionUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -149,9 +143,7 @@
}
}

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void WorkloadActionNoUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -175,9 +167,7 @@

#elif RETURNS_NON_CONSUMABLE_STRUCT_$ID$

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void OverheadActionUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -189,9 +179,7 @@
BenchmarkDotNet.Engines.DeadCodeEliminationHelper.KeepAliveWithoutBoxing(result);
}

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void OverheadActionNoUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -203,9 +191,7 @@
BenchmarkDotNet.Engines.DeadCodeEliminationHelper.KeepAliveWithoutBoxing(result);
}

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void WorkloadActionUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -217,9 +203,7 @@
NonGenericKeepAliveWithoutBoxing(result);
}

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void WorkloadActionNoUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand Down Expand Up @@ -250,9 +234,7 @@

#elif RETURNS_BYREF_$ID$

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void OverheadActionUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -264,9 +246,7 @@
BenchmarkDotNet.Engines.DeadCodeEliminationHelper.KeepAliveWithoutBoxing(value);
}

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void OverheadActionNoUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -280,9 +260,7 @@

private $WorkloadMethodReturnType$ workloadDefaultValueHolder = default($WorkloadMethodReturnType$);

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void WorkloadActionUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -294,9 +272,7 @@
BenchmarkDotNet.Engines.DeadCodeEliminationHelper.KeepAliveWithoutBoxing(ref alias);
}

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void WorkloadActionNoUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -321,9 +297,7 @@
}
#elif RETURNS_BYREF_READONLY_$ID$

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void OverheadActionUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -335,9 +309,7 @@
BenchmarkDotNet.Engines.DeadCodeEliminationHelper.KeepAliveWithoutBoxing(value);
}

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void OverheadActionNoUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -351,9 +323,7 @@

private $WorkloadMethodReturnType$ workloadDefaultValueHolder = default($WorkloadMethodReturnType$);

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void WorkloadActionUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -365,9 +335,7 @@
BenchmarkDotNet.Engines.DeadCodeEliminationHelper.KeepAliveWithoutBoxingReadonly(alias);
}

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void WorkloadActionNoUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -392,9 +360,7 @@
}
#elif RETURNS_VOID_$ID$

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void OverheadActionUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -404,9 +370,7 @@
}
}

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void OverheadActionNoUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -416,9 +380,7 @@
}
}

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void WorkloadActionUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand All @@ -428,9 +390,7 @@
}
}

#if NETCOREAPP3_0_OR_GREATER
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]
#endif
[System.Runtime.CompilerServices.MethodImpl(BenchmarkDotNet.Portability.CodeGenHelper.AggressiveOptimizationOption)]
private void WorkloadActionNoUnroll(System.Int64 invokeCount)
{
$LoadArguments$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -654,13 +654,14 @@ private MethodBuilder EmitActionImpl(string methodName, RunnableActionKind actio
}

// .method private hidebysig
// instance void OverheadActionUnroll(int64 invokeCount) cil managed
// instance void OverheadActionUnroll(int64 invokeCount) cil managed aggressiveoptimization
var toArg = new EmitParameterInfo(0, InvokeCountParamName, typeof(long));
var actionMethodBuilder = runnableBuilder.DefineNonVirtualInstanceMethod(
methodName,
MethodAttributes.Private,
EmitParameterInfo.CreateReturnVoidParameter(),
toArg);
toArg)
.SetAggressiveOptimizationImplementationFlag();
toArg.SetMember(actionMethodBuilder);

// Emit impl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ public abstract class BenchmarkAction

/// <summary>Gets or sets invoke multiple times callback.</summary>
/// <value>Invoke multiple times callback.</value>
public Action<long> InvokeMultiple { get; protected set; }
public Action<long> InvokeUnroll { get; protected set; }
public Action<long> InvokeNoUnroll{ get; protected set; }

/// <summary>Gets the last run result.</summary>
/// <value>The last run result.</value>
Expand Down
Loading