【问题标题】:Potential problems when using ProfileOptimization across versions跨版本使用 ProfileOptimization 时的潜在问题
【发布时间】:2016-07-08 12:17:48
【问题描述】:

为了提高我的程序在启动时的启动性能,我调用了:

ProfileOptimization.SetProfileRoot(path);
ProfileOptimization.StartProfile("profile");

我有一些问题:

我可以跨我的程序版本使用相同的 ProfileOptimization 配置文件吗?如果方法被更改或删除会怎样?

如果我使用一个配置文件但多次运行我的程序会怎样?

【问题讨论】:

    标签: .net optimization compilation .net-4.5 jit


    【解决方案1】:

    PerfView 文档说明如下:

    后台JIT具有以下特点

    1. 它在给定机器上的首次启动时不起作用。没有配置文件,因此没有任何东西可以充当指示要编译的内容的“神谕”。
    2. 如果以前发布的情况很好地表明了这次会发生什么,那么它就不能很好地工作。 例如,如果特定程序通常使用命令行参数调用,使其在每次启动时执行的操作非常不同,那么后台 JIT 将无法很好地用于启动案例。
    3. 不过,它会自行恢复。例如,如果程序经常与一组命令行参数一起使用,但偶尔会与另一组参数一起使用,这会导致它运行非常不同的代码路径,那么它将适用于大多数启动(但不是不寻常的命令,以及之后)。
    4. 您可以通过为同一应用程序引入更多配置文件来解决上述问题。如果您的配置文件不是在 START 而是在每个 COMMAND 的开头,那么运行时将为每个命令保留一个配置文件,并且每个命令都可以正常工作。
    5. 后台 JIT 编译往往只能将大约 1/2 的场景 JIT 时间推送到不影响端到端时间的后台。这是因为“主线程”通常可以“赶上”后台线程,并且在后台线程完成编译之前需要一个方法。在与 JIT 编译相关的 CPU 成本远大于执行 JIT 代码的典型情况下,这往往会导致一半的方法由主线程编译,一半由后台线程编译。这就是 NGENing 比后台 JIT 编译更好的地方。

    后台 JIT 编译会出现什么问题。

    如果您的程序使用了 SetProfileRoot 和 StartProfile,但 JIT 编译(如 JITStats 视图中所示)没有显示任何或很少的背景 JIT 编译,可能有几个问题。 从根本上说,一个重要的设计目标是确保后台 JIT 编译在任何情况下都不会改变程序的行为。 不幸的是,这意味着算法往往会迅速退出。特别是

    1. 加载模块时,可能会调用模块构造函数,这可能会产生副作用(即使这种情况非常罕见)。因此,如果后台 JITTing 会导致模块比其他情况更早加载,它可能会暴露(罕见的)错误。因为后台 JIT 有一个非常高的兼容性栏,它通过使用在 JIT 编译时加载的 EXACT 模块标记每个方法来防止这种情况发生,并且只允许在所有这些 EXACT 模块也加载后进行后台 JIT 编译当前运行。因此,如果您有一个场景(比如打开菜单),有时会加载更多或更少的模块(因为之前的用户操作导致加载不同的模块),那么后台 JIT 可能无法正常工作。
    2. 如果您已将回调附加到 System.Assembly.ModuleResolve 事件,如果 ModuleResolve 回调在第二次运行时返回的答案与其不同,后台 JITing 可能会产生副作用(尽管极不可能且设计非常糟糕)第一次运行。由于这个背景,第一次调用 ModuleResolve 回调时,JIT 编译会暂停。
    3. 因为任何模块查找失败,将在最终失败之前调用 ModuleResolve 事件,这意味着对失败模块的任何探测也将禁止后台 JIT 编译。

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 2019-05-11
      • 1970-01-01
      • 1970-01-01
      • 2022-11-29
      • 2017-11-05
      • 1970-01-01
      • 2013-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多