![](/img/trans.png)
[英]VisualStudio C# x64, why AddReference option, .NET tab points to x86 DLL instead of 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.