dotnet/runtime
Vedi su GitHubJit x86: improve codegen for compares with long statics
Open
#8555 aperta il 14 lug 2017
arch-x86area-CodeGen-coreclrenhancementhelp wantedoptimizationtenet-performance
Metriche repository
- Star
- (17.886 star)
- Metriche merge PR
- (Merge medio 12g 11h) (661 PR mergiate in 30 g)
Descrizione
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