【问题标题】:Can I avoid JIT in .NET?我可以在 .NET 中避免 JIT 吗?
【发布时间】:2010-10-01 13:34:44
【问题描述】:

如果我的代码总是要在特定的处理器上运行,如果我在安装过程中有这些信息,我是否有机会避免 JIT?

【问题讨论】:

    标签: .net jit


    【解决方案1】:

    使用NGEN:

    本机映像生成器 (Ngen.exe) 是一种提高托管应用程序性能的工具。 Ngen.exe 创建本机映像,这些文件包含已编译的特定于处理器的机器代码,并将它们安装到本地计算机上的本机映像缓存中。运行时可以使用缓存中的本机图像,而不是使用即时 (JIT) 编译器来编译原始程序集...

    有关使用 Ngen.exe 和本机映像服务的更多信息,请参阅Native Image Service...

    【讨论】:

    • 例如Paint.NET 使用它。
    • OP 询问安装时 JIT 避免,NGEN 与此相关。不过,对于那些想知道的人来说,NGEN 是每台机器的安装时的东西,而不是您可以在原始构建时使用的东西,即您不能分发 NGEN 的输出。 (如果我错了,请纠正我。)
    【解决方案2】:

    NGEN 是显而易见的答案,但我要指出,JIT 编辑的代码可以更快,因为它在运行时“知道”NGEN 无法做到的事情。我们利用这一事实在运行时根据我们的 .config 文件中的设置将代码行逐行删除:

    static readonly bool _EnableLogging = LoadFromConfigFile("EnableLogging");
    if (_EnableLogging && log.IsDebugEnabled)
    {
       //Do some logging
    }
    

    在此示例中,NGEN 必须在代码中保留 if 语句,因为它不知道 _EnableLogging 字段的值是什么。但是,JIT 确实知道 this run 的值,如果它为 false,则永远不会处理 if 语句,并且 JIT 会从它生成的机器代码中逐字忽略整个 if 语句,导致代码库更小,因此代码库更快。

    【讨论】:

    • 我知道这个答案现在有点老了,但我不相信这是正确的。 _EnableLogging 只有在代码运行时才会知道。 JIT 编译器正在尝试编译 IL 代码,以便它可以运行。如果它是true/false,它将不会执行代码来解决,因此将按原样编译if块。
    • 其实JIT确实知道,我只是举了一个不完整的例子。静态只读是一个类级别的变量,因此它在创建类时加载,if() 在一个方法中,所以它在以后的生活中是 JIT 的。我确认代码是使用 windbg 丢弃在地板上的,并在我们执行此操作时单步执行生成的机器代码。
    • +1 用于具体示例。向@dariom +1 提出一个导致@WaldenL 扩展他的答案的问题。非常有趣的话题。
    【解决方案3】:

    如果您在安装时有 CPU 信息,则不必避免 JIT。

    如果您使用 /platform:[x86/x64/IA64] 开关编译模块,编译器将在生成的 PE 文件中包含此信息,以便 CLR 将代码 JIT 到适当的 CPU 本机代码中并优化该 CPU 架构的代码。

    您可以使用NGEN,是的,但前提是您希望改善应用程序的启动,因为正在运行的进程中工作集减少,而不是因为您可以避免 JITting。您需要将 NGEN 文件的性能与非 NGEN 文件的性能进行实际比较,以确保 NGEN 文件更快。

    NGEN 无法像 JIT 编译器那样对执行环境做出尽可能多的假设,因此会产生未优化的代码。

    例如:它为静态字段访问添加了间接访问,因为实际 静态字段的地址只有在运行时才知道。

    【讨论】:

      猜你喜欢
      • 2022-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-08
      • 2018-12-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多