跨版本使用ProfileOptimization时可能出现的问题

时间:2016-07-08 12:17:49

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

为了提高我启动程序的启动性能,我打电话给:

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

我有一些问题:

我可以在我的程序版本中使用相同的ProfileOptimization配置文件吗?如果方法已被更改或删除会发生什么?

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

1 个答案:

答案 0 :(得分:1)

PerfView文档说明如下:

  

背景JIT具有以下特征

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

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

         

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

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

希望它有所帮助。