我正在用C#编写一个DSP应用程序(基本上是一个多轨编辑器)。我已经在不同的机器上进行了很长一段时间的分析,并且我注意到了一些“好奇”的东西。
在我的家用机器上,回放循环的第一次运行占用了可用时间的大约50%-60%,(我认为这是由于JIT完成其工作),然后对于后续循环,它会下降到稳定的5 % 消费。问题是,如果我在较慢的计算机上运行应用程序,第一次运行占用的时间超过可用时间,导致播放中断并弄乱输出音频,这是不可接受的。之后,它降至8%-10%的消费量。
即使在第一次运行之后,应用程序仍然不时地调用一些耗时的例程(每2秒或多或少),这导致稳定的5%消耗经历非常短的20%-25%的峰值。我注意到,如果我让应用程序运行一段时间,这些峰值也会下降到7%-10%。 (我不确定这是否是由于JIT重新编译这些代码部分)。
所以,我对JIT有一个严重的问题。虽然应用程序即使在非常慢的机器中也能很好地运行,但这些“编译风暴”将成为一个大问题。我正在试图弄清楚如何解决这个问题,我想出了一个想法,即用一个属性来标记所有“明智的”例程,该属性将告诉应用程序在启动时预先“挤压”它们因此,当他们真正需要时,他们将完全优化。但这只是一个想法(我也不太喜欢它),我想知道是否有更好的解决方案来解决整个问题。
我想听听你们的想法。
(NGEN应用程序不是一个选项,我喜欢并希望我能获得所有JIT优化。)
编辑:
内存消耗和垃圾收集没有问题,我正在使用对象池,播放期间的最大内存峰值为304 Kb。
您可以使用PrepareMethod
...方法触发JIT编译器在应用程序初始化例程期间编译整个程序集集(无需使用NGen
)。
这里有更详细的解决方案:Forcing JIT Compilation During Runtime。
初始速度确实听起来像Fusion + JIT,ILMerge(适用于Fusion)和NGEN(适用于JIT)可以提供帮助;您可以在启动时始终通过系统播放静音轨道,以便在没有用户注意到任何失真的情况下完成所有艰苦工作?
NGEN是一个不错的选择;有没有理由你不能使用它?
你在初始加载后提到的问题听起来并不像是与JIT有关。也许垃圾收集。
你尝试过分析吗? CPU和内存(集合)?
正如Marc所说,持续的峰值听起来不像JIT问题。其他要寻找的东西:
编辑:
即使您不想使用NGen,至少要比较一个NGen版本,这样您就可以看到JITing的不同之处
如果您认为自己受到JIT的影响,那么请使用NGEN预编译您的应用并再次运行测试。 NGEN编译的代码中没有JIT开销。如果您仍然在NGEN的应用程序中看到尖峰,那么您知道它们不是由JIT引起的。