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