dotnet/runtime

Jit should inline CORINFO_HELP_ASSIGN_REF (at least for hot paths)

Closed this issue · 2 comments

From Discord:
The following benchmark is 2x times faster on Mono-JIT (even without LLVM back-end):

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

public class Program
{
    object _o1, _o2, _o3, _o4;

    static void Main(string[] args) => BenchmarkRunner.Run<Program>();

    [Benchmark]
    [Arguments("1","2","3","4")]
    public void AssignRefs(object o1, object o2, object o3, object o4)
    {
        _o1 = o1;
        _o2 = o2;
        _o3 = o3;
        _o4 = o4;
    }
}

Results:

      |     Method |     Mean |     Error |    StdDev |
      |----------- |---------:|----------:|----------:|
 Mono | AssignRefs | 2.311 ns | 0.0144 ns | 0.0120 ns |
  CLR | AssignRefs | 4.839 ns | 0.0201 ns | 0.0188 ns |

Mono doesn't use any helpers here to assign oX to _oX and inlines all the memory barriers/xchg machinery to do that while coreclr invokes CORINFO_HELP_ASSIGN_REF for each assignment

Tagging subscribers to this area: @JulieLeeMSFT
See info in area-owners.md if you want to be subscribed.

Issue Details

From Discord:
The following benchmark is 2x times faster on Mono-JIT (even without LLVM back-end):

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

public class Program
{
    object _o1, _o2, _o3, _o4;

    static void Main(string[] args) => BenchmarkRunner.Run<Program>();

    [Benchmark]
    [Arguments("1","2","3","4")]
    public void AssignRefs(object o1, object o2, object o3, object o4)
    {
        _o1 = o1;
        _o2 = o2;
        _o3 = o3;
        _o4 = o4;
    }
}

Results:

      |     Method | o1 | o2 | o3 | o4 |     Mean |     Error |    StdDev |
      |----------- |--- |--- |--- |--- |---------:|----------:|----------:|
 Mono | AssignRefs |  1 |  2 |  3 |  4 | 2.311 ns | 0.0144 ns | 0.0120 ns |
  CLR | AssignRefs |  1 |  2 |  3 |  4 | 4.839 ns | 0.0201 ns | 0.0188 ns |

Mono doesn't use any helpers here to assign oX to _oX and inlines all the memory barriers/xchg machinery to do that while coreclr invokes CORINFO_HELP_ASSIGN_REF

Author: EgorBo
Assignees: -
Labels:

tenet-performance, area-CodeGen-coreclr, untriaged

Milestone: -

Ah, looks like CLR's ASSIGN_REF helpers are too complicated to be inlined 🙁 they do a lot of gc-specific work, perhaps could be somehow partially inlined or merged for subsequent assignments?