为什么 x86 JIT 比 x64 更智能? [英] Why x86 JIT is smarter than x64?

查看:21
本文介绍了为什么 x86 JIT 比 x64 更智能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在运行一个非常简单的程序

 static void Main(string[] args){Console.WriteLine(Get4S());Console.WriteLine(Get4());}私有静态 int Get4S(){返回 4;}私有静态 int Get4(){int res = 0;for (int i = 0; i <4; i++){资源++;}返回资源;}

当它在 x86 下工作时,它内联 Get4S 方法和 Get4 汇编代码是:

00000000 推送 ebp00000001 mov ebp,esp00000003 异或 eax,eax00000005 Inc eax00000006 Inc eax00000007 Inc eax00000008 Inc eax00000009 流行音乐 ebp0000000a ret

但是在 x64 下运行时,Get4S 方法得到相同的 asm,但 Get4 asm 根本没有优化:

00000000 xor eax,eax00000002 异或edx,edx00000004 Inc eax00000006 Inc edx00000008 cmp edx,40000000b jl 00000000000000040000000d ret

我假设 x64 JIT 展开循环,然后看到可以在编译时计算结果,并且将内联具有编译时结果的函数.但没有发生任何事情.

为什么 x64 在这种情况下如此愚蠢?..

解决方案

我明白了.这是因为在选择 x64 构建时使用 RyuJIT,即使选择了 .Net 4.5.2 目标平台.所以我通过在 App.Config 文件中添加此部分来修复它:

<预><代码><配置><运行时><useLegacyJit enabled="1"/></运行时></配置>

此标记启用传统"x64 JIT(在引号中,因为我认为他比闪亮的"RyuJIT 好得多),并且 main 方法中的结果 ASM 是:

00000000 sub rsp,28h00000004 mov ecx,400000009 呼叫 000000005EE758700000000e mov ecx,400000013 呼叫 000000005EE7587000000018 nop00000019 添加 rsp,28h0000001d ret

这两种方法都是在编译时计算的,并通过它们的值内联.

结论:.Net 4.6 安装后,对于CLR4.0 下的所有解决方案,旧的 x64 jitter 被替换为 RyuJIT.所以关闭它的唯一方法是 useLegacyJit 开关或 COMPLUS_AltJit 环境变量

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

这篇关于为什么 x86 JIT 比 x64 更智能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆