.NET Core:方法 MethodImplOptions.AggressiveOptimization 究竟是做什么的?

11
MethodImplOptions.AggressiveOptimization 是做什么的?微软官方文档并没有提供很多信息。在哪些情况下可以使用它?
1个回答

8
我会寻找更详细的信息(如果这是你要找的),而不是在文档中,而是在.net core github发布说明中。让我们从后者开始看起。对于 .net core 3.0,我们可以找到以下条目:
完全优化的JIT会更慢地生成更高质量(或更优化)的代码。对于不使用 Quick JIT 的方法(例如,如果该方法带有 MethodImplOptions.AggressiveOptimization 特性),将使用完全优化的JIT。
因此,首先我们知道,如果一个方法被标记为这样的属性,它应该使用完全优化的JIT进行JIT编译,这可能会产生更好、更优化的代码 - 但需要更长的编译时间。
现在让我们关注github,看看我们能在那里找到什么。这个ticket中讨论了这个问题,并且对这个主题提供了更多的细节。
该标志可以用于MethodImplAttribute中,以指示该方法包含热代码:
  • 对于分层编译,它可以立即使用第一层JIT来处理该方法[...]
  • 它可以允许JIT花更多的时间生成更好的代码,例如更积极地将代码内联到函数中
从这里我们可以得到一个答案,在哪些情况下可以使用它,以及它在底层正在执行什么操作。
在处理热路径代码的情况下,此属性有助于JIT进行更快,更优化的代码生成,而不是进行分层编译。在开始时使用更多的时间如果运行时检测到它实际上处于热路径上,则可以节省后面的时间。
还有一个有趣的讨论,关于该标志的其他用途,您可以阅读。
但是最终的真相(我希望如此)和提交与此讨论相关,因此我们可以查看它们。通过这些提交和提交消息,我们可以了解到这实际上是分层编译和JIT所发生的事情(至少这是我所看到的)。

那么这个标志只对分层编译有用,否则什么也没做? - codymanix
这至少是我能找到的。 - Paweł Łukasik
1
它目前做了两件事:(1)使该方法不适合预编译和(2)使该方法不适合分层编译。其净结果是,当首次调用方法时,该方法总是被jitted,并且已经被优化。仅在发现运行该方法的预编译或Tier0代码会导致不良影响(性能损失或额外分配)时使用此标志。如果您没有看到这些不良影响,则最好不要使用该标志;通常情况下,常规Tier1代码的表现比AggressiveOptimization代码更好。 - Andy Ayers
1
@Redhouane 你应该知道什么是适合你的热代码(分析?)。有关JIT如何知道哪些方法是更好的候选项以进行更好的Jitting的更多信息可以在此处找到:https://github.com/dotnet/coreclr/blob/master/Documentation/design-docs/tiered-compilation.md。 - Paweł Łukasik
@AndyAyers:你说的“表现更好”是指加载时间,还是其他方面也可以更好? - codymanix
1
JIT生成的代码在进行普通Tier1重新编译时通常比使用AggressiveOptimization生成的代码更优化。关键区别在于方法的优化版本何时被JIT编译。对于普通的Tier1 JIT编译发生在进程生命周期的后期,因此JIT可以更好地利用已初始化的类--因此普通的Tier1 JIT编译代码将不需要太多的类初始化检查,并且可以合并来自已初始化类的只读静态值和类型。使用AggressiveOptimization的方法会更早地进行JIT编译,因此在这里失去了优势。 - Andy Ayers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接