-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
This benchmark is around 200x slower when running in ios-like configuration (composite r2r + interp fallback) on desktop, compared to default (jit).
Interestingly enough, after profiling, it turns out that most of the time spent is not in interpreting methods but rather in R2R machinery. In order to reproduce, the application was compiled with composite-r2r. The minimal runtime configuration diff that reproduces this issue is BrzVlad@3a4d118. At runtime, tiering has to be disabled as well (DOTNET_TieredCompilation=0).
Most of the time spent originates in ExternalMethodFixupWorker, which is called for every benchmark iteration, suggesting that a callsite from r2r is not properly patched. The runtime seems to attempt to resolve the call for each microbenchmark iteration, with excessive time spent related to signature decoding. Attached a profile showing the amount of time spent in the hottest methods.
Even when running with composite-r2r with jit fallback, the benchmark was still 50x slower than normal jit, with the above runtime configuration. Microbenchmark extracted from https://github.com/dotnet/performance/blob/main/src/benchmarks/micro/runtime/Devirtualization/DefaultEqualityComparerPerf.cs#L79
using System;
using System.Runtime.CompilerServices;
using System.Collections.Generic;
using System.Globalization;
public class EqualityComparerFixture<T> where T : IEquatable<T>
{
IEqualityComparer<T> comparer;
public EqualityComparerFixture()
{
comparer = EqualityComparer<T>.Default;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public bool CompareCached(ref T a, ref T b)
{
return comparer.Equals(a, b);
}
}
public class Program {
public enum E {
RED = 1,
BLUE = 2
}
private EqualityComparerFixture<ValueTuple<byte, E, int>> valueTupleFixture = new EqualityComparerFixture<ValueTuple<byte, E, int>>();
private ValueTuple<byte, E, int> v0 = new ValueTuple<byte, E, int>(3, E.RED, 11);
public bool ValueTupleCompareCached() => valueTupleFixture.CompareCached(ref v0, ref v0);
public void BenchCompareTuple()
{
for (int j = 0; j < 100000000; j++)
ValueTupleCompareCached();
Console.WriteLine ("Benchmarked compare tuple");
}
public static void Main(string[] args)
{
Program p = new Program();
p.BenchCompareTuple();
}
}