Skip to content

PGO: redundant Tier0-instr promotions #84517

Open

Description

@EgorBo
static void Main()
{
    for (int i = 0; i < 100; i++)
    {
        Test();
        var _ = Test2;
        Thread.Sleep(16);
    }
}

[MethodImpl(MethodImplOptions.NoInlining)]
static int Test1()
{
    int sum = 0;
    for (int i = 0; i < 10; i++)
        sum += i;
    return sum;
}

static int Test2 { get; set; }

Actual result:

 147: JIT compiled Prog:Test1():int [Instrumented Tier0, IL size=21, code size=109, hash=0x792ae54b]
 311: JIT compiled Prog:Test1():int [Instrumented Tier0, IL size=21, code size=109, hash=0x792ae54b]
 313: JIT compiled Prog:Test1():int [Tier1 with Dynamic PGO, IL size=21, code size=14, hash=0x792ae54b]

 152: JIT compiled Prog:get_Test2():int [Tier0, IL size=6, code size=12, hash=0xf8310770]
 316: JIT compiled Prog:get_Test2():int [Instrumented Tier0, IL size=6, code size=12, hash=0xf8310770]
 319: JIT compiled Prog:get_Test2():int [Tier1, IL size=6, code size=7, hash=0xf8310770]

Since Test1 has a loop we always instrument it in Tier0, but then it's promoted to Instrumented Tier0 again - it can be omitted.

Also, all Tier0 methods should warn VM in advance that they don't need instrumentation at all (e.g. simple auto properties like get_Test2).

cc @AndyAyersMS

Activity

  1. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Apr 8, 2023
  2. ghost added
    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
    on Apr 8, 2023
  3. self-assigned this
    on Apr 8, 2023
  4. removed
    untriagedNew issue has not been triaged by the area owner
    on Apr 8, 2023
  5. added this to the 8.0.0 milestone on Apr 8, 2023
  6. AndyAyersMS commented on Apr 12, 2023

    @AndyAyersMS
    Member

    Even more interesting when OSR gets involved:

     832: JIT compiled Benchstone.BenchI.MulMatrix:Inner(int[][],int[][],int[][]) [Instrumented Tier0, IL size=435, code size=2943, hash=0x482bb336]
     833: JIT compiled Benchstone.BenchI.MulMatrix:Inner(int[][],int[][],int[][]) [Tier1-OSR @0x60 with Dynamic PGO, IL size=435, code size=1323, hash=0x482bb336]
     834: JIT compiled Benchstone.BenchI.MulMatrix:Inner(int[][],int[][],int[][]) [Tier1-OSR @0x2a with Dynamic PGO, IL size=435, code size=1529, hash=0x482bb336]
     835: JIT compiled Benchstone.BenchI.MulMatrix:Inner(int[][],int[][],int[][]) [Instrumented Tier0, IL size=435, code size=2943, hash=0x482bb336]
     836: JIT compiled Benchstone.BenchI.MulMatrix:Inner(int[][],int[][],int[][]) [Tier1-OSR @0x60 with Dynamic PGO, IL size=435, code size=1323, hash=0x482bb336]
     837: JIT compiled Benchstone.BenchI.MulMatrix:Inner(int[][],int[][],int[][]) [Tier1-OSR @0x2a with Dynamic PGO, IL size=435, code size=1547, hash=0x482bb336]
     838: JIT compiled Benchstone.BenchI.MulMatrix:Inner(int[][],int[][],int[][]) [Tier1 with Dynamic PGO, IL size=435, code size=1194, hash=0x482bb336]
    
  7. EgorBo commented on Apr 12, 2023

    @EgorBo
    MemberAuthor

    Even more interesting when OSR gets involved:

     832: JIT compiled Benchstone.BenchI.MulMatrix:Inner(int[][],int[][],int[][]) [Instrumented Tier0, IL size=435, code size=2943, hash=0x482bb336]
     833: JIT compiled Benchstone.BenchI.MulMatrix:Inner(int[][],int[][],int[][]) [Tier1-OSR @0x60 with Dynamic PGO, IL size=435, code size=1323, hash=0x482bb336]
     834: JIT compiled Benchstone.BenchI.MulMatrix:Inner(int[][],int[][],int[][]) [Tier1-OSR @0x2a with Dynamic PGO, IL size=435, code size=1529, hash=0x482bb336]
     835: JIT compiled Benchstone.BenchI.MulMatrix:Inner(int[][],int[][],int[][]) [Instrumented Tier0, IL size=435, code size=2943, hash=0x482bb336]
     836: JIT compiled Benchstone.BenchI.MulMatrix:Inner(int[][],int[][],int[][]) [Tier1-OSR @0x60 with Dynamic PGO, IL size=435, code size=1323, hash=0x482bb336]
     837: JIT compiled Benchstone.BenchI.MulMatrix:Inner(int[][],int[][],int[][]) [Tier1-OSR @0x2a with Dynamic PGO, IL size=435, code size=1547, hash=0x482bb336]
     838: JIT compiled Benchstone.BenchI.MulMatrix:Inner(int[][],int[][],int[][]) [Tier1 with Dynamic PGO, IL size=435, code size=1194, hash=0x482bb336]
    

    Heh indeed funny one but presumably the same issue, I'll fix it this week

  8. ghost added
    in-prThere is an active PR which will close this issue when it is merged
    on Apr 13, 2023
  9. AndyAyersMS commented on Apr 20, 2023

    @AndyAyersMS
    Member

    We can also see this when we have a nontrivial intrinsic R2R method; we rejit at tier1-instr but it doesn't actually instrument; then we rejit at tier1 and don't have any dynamic PGO data, so we are jitting twice and probably producing the same code each time.

     841: JIT compiled System.Memory.Span`1[ubyte]:SequenceEqual():bool:this [Tier0, IL size=28, code size=151, hash=0xbffeed85]
    **877: JIT compiled System.SpanHelpers:SequenceEqual(byref,byref,ulong):bool [Instrumented Tier1 with Static PGO, IL size=612, code size=302, hash=0xacbc5054]**
     878: JIT compiled System.Memory.Span`1[ubyte]:SequenceEqual():bool:this [Instrumented Tier0, IL size=28, code size=151, hash=0xbffeed85]
     881: JIT compiled System.MemoryExtensions:SequenceEqual[ubyte](System.Span`1[ubyte],System.ReadOnlySpan`1[ubyte]):bool [Instrumented Tier1, IL size=96, code size=42, hash=0x608a246a]
    **882: JIT compiled System.SpanHelpers:SequenceEqual(byref,byref,ulong):bool [Tier1 with Static PGO, IL size=612, code size=302, hash=0xacbc5054]**
     883: JIT compiled System.Memory.Span`1[ubyte]:SequenceEqual():bool:this [Tier1, IL size=28, code size=81, hash=0xbffeed85]
     886: JIT compiled System.MemoryExtensions:SequenceEqual[ubyte](System.Span`1[ubyte],System.ReadOnlySpan`1[ubyte]):bool [Tier1, IL size=96, code size=42, hash=0x608a246a]
    
  10. ghost removed
    in-prThere is an active PR which will close this issue when it is merged
    on Jul 11, 2023
  11. EgorBo commented on Aug 5, 2023

    @EgorBo
    MemberAuthor

    Moving to 9.0 as the VM change was not trivial. We think that this doesn't really affect perf or startup but still nice to fix

  12. modified the milestones: 8.0.0, 9.0.0 on Aug 5, 2023
  13. added
    Priority:2Work that is important, but not critical for the release
    on May 6, 2024
  14. EgorBo commented on Jul 18, 2024

    @EgorBo
    MemberAuthor

    Moving to post-P7 as it's not a correctness problem

  15. removed
    Priority:2Work that is important, but not critical for the release
    on Jul 18, 2024
  16. modified the milestones: 9.0.0, Future on Aug 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions