gpt4 book ai didi

.net - 记录 CLR JIT 策略

转载 作者:行者123 更新时间:2023-12-03 21:48:04 26 4
gpt4 key购买 nike

我想知道 CLR 适用于 JIT 编译的范围和顺序。

例如,如果我的应用程序只调用给定类的一个方法,那么该类未使用的方法是否会进行不必要的 JIT 编译?如果是,它们是在执行我需要的一个方法之前全部进行 JIT 编译,还是在事后延迟编译?

那么方法中的分支呢? CLR 是否允许编译方法中的一半代码,同时允许同一方法中的单独分支在需要时保持未编译状态?

似乎随着时间的推移,我已经找到了一些文章,可以瞥见其中的一些细节,但现在我没有找到任何内容来提供关于 CLR 如何以及何时选择 JIT 的一部分的统一的、可读的摘要代码。有什么推荐的书籍或链接吗?

如果任何此类指南能够按 .net 版本分解此类 JIT 决策逻辑,那将是最好的。

最佳答案

JIT 在 .NET 中的工作方式是,在方法被 jit 之前,方法表入口指向一个小 stub ,该 stub 将在调用时对方法进行 JIT。之后更新方法表以引用 JIT 编译代码的位置。

鉴于只有被调用的方法是 JIT 编译的,因此对于未被调用的方法没有 JIT 开销。

JIT 编译器会在需要时编译整个方法。如果它是发布构建代码,则可能会被优化掉,否则该方法将被完整编译。

您可以使用 WinDbg/SOS 检查方法表。请考虑以下事项:

class SomeType
{
public void Called()
{
Console.WriteLine("called");
}

public void NotCalled()
{
Console.WriteLine("not called");
}
}

假设我们创建了一个 SomeType 的实例,调用 Called 然后检查 SomeType 的方法表。在 x86 上,您会看到类似这样的内容:

0:000> !dumpmt -md 00a7381c
EEClass: 00a712d0
Module: 00a72e94
Name: ConsoleApplication1.SomeType
mdToken: 02000002
File: c:\temp\ConsoleApplication1\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe
BaseSize: 0xc
ComponentSize: 0x0
Slots in VTable: 7
Number of IFaces in IFaceMap: 0
--------------------------------------
MethodDesc Table
Entry MethodDe JIT Name
72ca4960 729a6728 PreJIT System.Object.ToString()
72c98790 729a6730 PreJIT System.Object.Equals(System.Object)
72c98360 729a6750 PreJIT System.Object.GetHashCode()
72c916f0 729a6764 PreJIT System.Object.Finalize()
00df00d8 00a73814 JIT ConsoleApplication1.SomeType..ctor()
00df0110 00a737fc JIT ConsoleApplication1.SomeType.Called()
00a7c031 00a73808 NONE ConsoleApplication1.SomeType.NotCalled()

注意 Called 是 JIT 编译的,但是由于我们还没有调用 NotCalled,所以它还没有被 JIT 编译。

另外,请注意 object 中的方法都已经过 PreJIT 编译。

请记住,在发布版本中,短方法​​可能会被内联,在这种情况下,它们不会作为方法被调用,而只是作为调用站点生成的代码的一部分包含在内。

关于.net - 记录 CLR JIT 策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14841384/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com