Why is x86 JIT smarter than x64?

I am running a very simple program

    static void Main(string[] args)
    {
        Console.WriteLine(Get4S());
        Console.WriteLine(Get4());
    }

    private static int Get4S()
    {
        return 4;
    }

    private static int Get4()
    {
        int res = 0;
        for (int i = 0; i < 4; i++)
        {
            res++;
        }
        return res;
    }

      

when it works under x86

, it encloses the asm method Get4S

and Get4

code:

00000000  push        ebp 
00000001  mov         ebp,esp 
00000003  xor         eax,eax 
00000005  inc         eax 
00000006  inc         eax 
00000007  inc         eax 
00000008  inc         eax 
00000009  pop         ebp 
0000000a  ret 

      

BUT when working under x64 we get the same asm method for a method Get4S

, but Get4

asm is not optimized at all:

00000000  xor         eax,eax 
00000002  xor         edx,edx 
00000004  inc         eax 
00000006  inc         edx 
00000008  cmp         edx,4 
0000000b  jl          0000000000000004 
0000000d  ret 

      

I assumed that the x64

JIT unwraps the loop and then sees that the result can be computed at compile time, and the compile-time function will be included. But none of this happened.

Why is it x64

so stupid in this case? ..

+1


source to share


1 answer


I understood. This is because RyuJIT is used when selecting x64

build even if the target platform is selected .Net 4.5.2

. So I fixed it by adding this section to the App.Config file:

<configuration>
  <runtime>
    <useLegacyJit enabled="1" />
  </runtime>
</configuration>

      

This markup allows for "legacy" x64 JITs (quoted because I think it's much better than the "shiny" RyuJIT) and the ASM result in the main method is:



00000000  sub         rsp,28h 
00000004  mov         ecx,4 
00000009  call        000000005EE75870 
0000000e  mov         ecx,4 
00000013  call        000000005EE75870 
00000018  nop 
00000019  add         rsp,28h 
0000001d  ret 

      

both methods were evaluated at compile time and within their values.

Conclusion: When installed .Net 4.6

, the old x64 jitter is replaced with RyuJIT

for all solutions under CLR4.0

. So the only way to turn it off is with a useLegacyJit

switch or COMPLUS_AltJit

an environment variable

+4


source







All Articles