簡體   English   中英

為什么x86 JIT比x64更聰明?

[英]Why x86 JIT is smarter than x64?

我正在運行一個非常簡單的程序

    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;
    }

x86下工作時,它將內聯Get4S方法,而Get4 asm代碼為:

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 

但是在x64下運行時,我們會為Get4S方法獲得相同的asm,但是Get4 asm並未進行任何優化:

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

我以為x64 JIT展開了循環,然后看到可以在編譯時計算結果,並且將內聯具有編譯時結果的函數。 但是什么也沒發生。

為什么在這種情況下x64如此愚蠢?

我明白了。 這是因為即使選擇了.Net 4.5.2目標平台,當選擇x64構建時也會使用RyuJIT。 所以我通過在App.Config文件中添加此部分來修復它:

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

此標記啟用“舊版” x64 JIT(用引號引起來,因為我認為他比“發光的” RyuJIT更好),結果主要方法中的ASM為:

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 

兩種方法都是在編譯時計算的,並按其值進行內聯。

結論:安裝.Net 4.6 ,對於CLR4.0下的所有解決方案, RyuJIT將替換舊的x64抖動。 因此,關閉它的唯一方法是useLegacyJit開關或COMPLUS_AltJit環境變量

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM