6

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

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

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

4

1 回答 1

11

NGen 和 RyuJIT 之间没有足够的区别让你开心。它们做的工作非常不同,NGen 提前 jit 和 RyuJIT 在进程运行时及时 jit。但是 NGen 没有自己的抖动,它要求 RyuJIT 完成工作。生成的机器代码并没有根本的不同。有一些优化无法预先完成,NGen-ed 代码稍慢。

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

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

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

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

于 2015-11-11T10:15:36.673 回答