14

我正在用 C# 编写一个 DSP 应用程序(基本上是一个多轨编辑器)。我已经在不同的机器上对它进行了很长一段时间的分析,我注意到了一些“好奇”的东西。

在我的家用机器上,播放循环的第一次运行占用了大约 50%-60% 的可用时间(我认为这是由于 JIT 完成了它的工作),然后对于后续循环,它会下降到稳定的 5 % 消耗。问题是,如果我在较慢的计算机上运行应用程序,第一次运行占用的时间超过可用时间,导致播放中断并弄乱输出音频,这是不可接受的。之后,它下降到 8%-10% 的消耗。

即使在第一次运行之后,应用程序也会不时地调用一些耗时的例程(或多或少每 2 秒一次),这导致稳定的 5% 消耗经历了 20%-25% 的非常短的峰值。我注意到,如果我让应用程序运行一段时间,这些峰值也会下降到 7%-10%。(我不确定这是否是由于 JIT 重新编译了这些代码部分)。

所以,我对 JIT 有一个严重的问题。虽然应用程序即使在非常慢的机器上也能很好地运行,但这些“编译风暴”将是一个大问题。我试图弄清楚如何解决这个问题,我想出了一个想法,即用一个属性标记所有“合理”例程,该属性将告诉应用程序在启动期间预先“挤压”它们,因此在真正需要时会对其进行全面优化。但这只是一个想法(我也不太喜欢它),我想知道是否有更好的解决方案来解决整个问题。

我想听听你们的想法。

(NGEN 应用程序不是一个选项,我喜欢并想要我可以获得的所有 JIT 优化。)

编辑:

内存消耗和垃圾回收不是问题,我使用的是对象池,播放期间的最大内存峰值为 304 Kb。

4

4 回答 4

17

您可以触发 JIT 编译器在应用程序的初始化例程期间使用 ... 方法编译整个程序集PrepareMethod(无需使用NGen)。

此处更详细地描述了此解决方案:在运行时强制 JIT 编译

于 2010-08-03T19:45:23.573 回答
4

初始速度确实听起来像 Fusion+JIT,ILMerge(对于 Fusion)和 NGEN(对于 JIT)会有所帮助;您总是可以在启动时通过系统播放无声曲目,这样就可以完成所有艰苦的工作而用户不会注意到任何失真?

NGEN 是一个不错的选择;你有理由不能使用它吗?

您在初始加载提到的问题听起来与 JIT 无关也许是垃圾收集。

你试过剖析吗?CPU 和内存(集合)?

于 2009-04-15T11:12:17.977 回答
3

正如 Marc 所提到的,持续的峰值听起来不像是 JIT 问题。其他要寻找的东西:

  • 垃圾收集 - 您是否在音频处理期间分配内存?如果您正在创建大量垃圾,甚至是在 Gen 0 集合中幸存的对象,这可能会导致明显的峰值。听起来您正在做某种预分配,但要注意库代码中的隐藏分配(即使是 foreach 循环也可以分配!)

  • 非规范化。在处理可能导致 CPU 峰值的非常小的浮点数时,某些类型的处理器存在问题。有关详细信息,请参阅http://www.musicdsp.org/files/denormal.pdf

编辑:

即使您不想使用 NGen,至少也要比较 NGen 的版本,这样您就可以看到 JITing 的不同之处

于 2009-04-15T14:18:34.800 回答
2

如果您认为自己受到 JIT 的影响,请使用 NGEN 预编译您的应用程序并再次运行测试。NGEN 编译的代码中没有 JIT 开销。如果您仍然在 NGEN 的应用程序中看到峰值,那么您知道它们不是由 JIT 引起的。

于 2010-08-03T19:56:26.437 回答