I'm 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 inlines Get4S
method and Get4
asm code is:
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 running under x64 we get same asm for Get4S
method, 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 supposed that x64
JIT unroll the loop, then see that result can be computed in compile-time, and function with compile-time result will be inlined. But nothing from it happend.
Why x64
is so stupid in this case?..
I got the point. It's because RyuJIT is used when x64
build is selected, even if .Net 4.5.2
target platform is selected. So i fixed it by adding this section in App.Config file:
<configuration>
<runtime>
<useLegacyJit enabled="1" />
</runtime>
</configuration>
This markup enables "legacy" x64 JIT (in quotes, because I think he's much better than "shiny" RyuJIT), and result ASM in 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 was calculated in compile time and inlined by theirs values.
Conclusion: When .Net 4.6
is installed, old x64 jitter is replaced by RyuJIT
for all solutions under CLR4.0
. So only way to turn it off is useLegacyJit
switch or COMPLUS_AltJit
environment variable