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

Posted

技术标签:

【中文标题】Ngen vs RyuJIT - (预)启动时最快的 x64 运行代码无关紧要【英文标题】:Ngen vs RyuJIT - fastest x64 running code when (pre-)startup does not matter 【发布时间】:2015-11-11 09:22:34 【问题描述】:

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

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

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

【问题讨论】:

【参考方案1】:

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 抖动。

【讨论】:

汉斯,你对 .NET JIT 代码质量的称赞让我心碎。 @Hans Passant 感谢您提供非常详细的回答! 'NGen-ed 代码稍慢。 - 您的意思只是启动阶段(由于需要找到磁盘上的其他文件并将其加载到内存中)还是有其他原因?不幸的是,我们有一些关键的代码路径(订单发送),即使是第一次执行也必须快速执行(JIT 配置文件可能是要走的路 - 但 Ngen 在这方面仍然更可靠) @usr - 你戴着灰色眼镜阅读我的帖子。称赞??我没有跳过 .NET Native。 @Jan - 不,机器代码稍慢。我避免谈论冷启动和热启动,因为您表示您不关心。我不得不说,您如此关注速度却似乎不知道您的代码是否足够快,这很奇怪。使用真实数据集运行性能测试并使用分析器查找热点是强制性的。没有人会为你这样做。 @Hans Passant:有效点。然而,通常很难在 Qs 中给出完整的相关和简洁的上下文(所以它可能有点误导)。我们在 4.5 中测量了关键路径(使用 Ngen 的第一次执行时间约为 200 微秒,而没有它的情况下大约有几十毫秒)。我们对其他代码性能进行了持续的统计评估。这些阻止我们升级到 4.5.1 和 4.5.2。然而,那些评估相当整体的性能。任何特定的信息主题都可以帮助关注新添加的指标(尤其是现在不仅要决定是否升级,因为我们需要新的 GC 功能)。

以上是关于Ngen vs RyuJIT - (预)启动时最快的 x64 运行代码无关紧要的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Wix 和项目参考部署本机映像 (NGen)

Visual Studio 2012安装:ngen挂起/什么都不做

你有没有用过ngen.exe?

RyuJIT的华丽转身

确定是不是正在使用 GAC 和 NGen 的程序集

c#程序打包机器代码生成(Ngen.exe)