Ngen vs RyuJIT - 最快的 x64 运行 代码(预)启动无关紧要

Ngen vs RyuJIT - fastest x64 running code when (pre-)startup does not matter

Ngen 和 RyuJIT 在 .NET 4.6 下是两个完全不相关的东西吗(尤其是不同的优化技术和算法)?

如果我们不关心 jitting 本身的成本,什么会产生最快(更好优化)的 x64 本机代码 and/or cold/warm 启动时间?

我们是 运行 一个很长的 运行 服务器应用程序。连续 运行 阶段在性能方面非常重要。 (预)启动阶段对我们来说并不重要。到目前为止,我们一直在使用 .NET 4.5,并且始终由 Ngen 生成本机图像。 我们现在正在升级到 .NET 4.6,我们希望确保这不会降低我们连续 运行 阶段的性能。我已经阅读了一些信息,表明 RyuJIT 是改善 JITing 时间的绝佳选择,但与 Ngen 相比,jited 代码的优化程度较低 - 参见例如this github comment on one of the RyuJIT bugs

NGen 和 RyuJIT 之间没有足够的差异让您满意。他们做 非常 不同的工作,NGen 提前 jit 和 RyuJIT 及时 jit,而过程是 运行。但是 NGen 没有自己的抖动,它要求 RyuJIT 来完成工作。生成的机器代码并没有根本的不同。有一些优化无法预先完成,NGen-ed 代码稍慢。

从技术上讲,NGen 可以做得更好,因为优化器可以花更多时间分析代码并尝试找到最佳优化。但微软并没有利用这一点。这不完全是 crystal 为什么他们不这样做,但肯定与他们的 1-800 支持 phone 号码有关。代码优化始终是代码生成器中风险最大的部分,现有抖动中的错误一直是优化错误。这可能有一天会改变并不是不可想象的。

当您可以利用 .NET Native 时,您就领先了。它使用 C++ 编译器的后端提前生成代码。但是目前,并且肯定会在未来相当长一段时间内,它只支持打包的应用程序。通过 Windows Store 交付的那种,您必须定位 Store、Phone 或 Universal,并使用 Store 作为部署工具。该包对于使 .NET Native 工作非常重要,只有这样才能看到需要翻译的代码。而且它通常仍然需要帮助才能正确处理,反射是一个很难解决的问题,这就是你在你的机器上安装它的原因。请注意,NGen 不存在相同的问题,它仍然依赖于抖动来及时抖动一些 代码。像反射目标代码和泛型。这可能有一天会改变并不是不可想象的。

如前所述,NGen 代码稍慢。因此,如果您不关心热启动延迟,那么您就不想使用 NGen。

最后但同样重要的是,RyuJIT 而非 生成的代码比其前身更快。这已经做了非常不错的优化工作。太体面了。 RyuJIT 项目开始修复遗留 x64 抖动中的问题,这种问题在代码库中非常基础,只能通过大幅重写来解决。优化就是其中之一,它对花在这上面的时间没有上限。在大型方法上给它非常不合理的 jitting 时间。因此,如果您想榨取最后一盎司,那么您应该尝试有意禁用 RyuJIT,使其回落到传统的 x64 抖动。