dotnet/runtime
Ver no GitHubJit x86: improve codegen for compares with long statics
Open
#8.555 aberto em 14 de jul. de 2017
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