dotnet/runtime

Jit x86: improve codegen for compares with long statics

Open

#8.555 aberto em 14 de jul. de 2017

Ver no GitHub
 (2 comments) (0 reactions) (0 assignees)C# (5.445 forks)batch import
arch-x86area-CodeGen-coreclrenhancementhelp wantedoptimizationtenet-performance

Métricas do repositório

Stars
 (17.886 stars)
Métricas de merge de PR
 (Mesclagem média 12d 11h) (661 fundiu PRs em 30d)

Description

For current x86 jit codegen, it appears long statics must be fully loaded into registers before they can be compared. For example:

using System;
using System.Runtime.CompilerServices;

class L
{
    static long Iterations;

    [MethodImpl(MethodImplOptions.NoInlining)]
    static int F(int x)
    {
        return x + 1;
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    static int Test()
    {
        int j = 0;

        for (int i = 0; i < Iterations; i++)
        {
            j = F(j);
        }

        return j;
    }

    public static int Main()
    {
        int i = 1000000;
        Iterations = i;
        int j = Test();
        return j == i ? 100 : 0;
    }
}
;; RyuJit x86
G_M25199_IG03:
       8BC8         mov      ecx, eax
       FF158C49EA00 call     [L:F(int):int]
       46           inc      esi
       8BD6         mov      edx, esi
       8BCA         mov      ecx, edx
       C1F91F       sar      ecx, 31
       8D3D5848EA00 lea      edi, [classVar[0xea493c]]
       8B1F         mov      ebx, dword ptr [edi]
       3B4F04       cmp      ecx, dword ptr [edi+4]
       7F06         jg       SHORT G_M25199_IG04
       7CE1         jl       SHORT G_M25199_IG03
       3BD3         cmp      edx, ebx
       72DD         jb       SHORT G_M25199_IG03

Jit32 will fetch the pieces from memory directly, which reduces register cross-section. Jit32 also defers reading the low part of of the static until it's needed:

;; Jit32
G_M25199_IG03:
       FF15FC46FF00 call     [L:F(int):int]
       8BC8         mov      ecx, eax
       46           inc      esi
       8BC6         mov      eax, esi
       C1F81F       sar      eax, 31
       3B05CC45FF00 cmp      eax, dword ptr [classVar[0xff46ac]+4]
       7F0A         jg       SHORT G_M25199_IG04
       7CE8         jl       SHORT G_M25199_IG03
       3B35C845FF00 cmp      esi, dword ptr [classVar[0xff46ac]]
       72E0         jb       SHORT G_M25199_IG03

This pattern appears in the inner iteration loop of many of the perf benchmarks since the Benchmark.InnerIterationCount property is a long.

category:cq theme:basic-cq skill-level:expert cost:small impact:small

Guia do colaborador