我想将音频计算委托给 C++ 层,但通过 WPF GUI 处理和编辑音频内容。
我简要了解了 C++/CLI,我想知道:
编辑:随着激烈的战争可能开始。 这是指向“基准测试游戏”的链接,它清楚地表明 C/C++ 是速度赢家。 我问:我应该在 C++ Dll 中编写 C++,还是在 C++CLI 程序集中编写 C++。
ref class
)及其成员被编译为 MSIL。 这意味着不使用 SIMD,并且需要更少的优化(至少在当前版本的 .NET 中,并且 Microsoft 给出的原因不会很快改变,尽管他们可能会改变对权衡的评估)。
另一方面,本机类型可以编译为 MSIL 或本机机器代码。 尽管 Visual C++ 没有世界上最好的 C++ 优化器,但它非常非常好。 所以我的建议是编译为本机代码。 在托管代码和本机代码之间调用时,Visual C++ 将使用 C++ 互操作,这是非常高效的(这与用于所有 .NET 内置函数(例如字符串连接)的
internalcall
技术相同)。
为了实现这一点,您可以将时间关键的代码放在一个单独的目标文件中(而不是单独的 DLL!,让链接器将托管和非托管代码组合在一起形成“混合模式”程序集),无需
/clr
进行编译,或用
#pragma managed(push, off)
... #pragma managed(pop)
括起来。 无论哪种方式都会为您带来最大程度的优化,并允许您使用 SIMD 内在函数来实现非常快速的代码。因此,这取决于问题:最简单的问题是一个接口,它通过 C++/CLI 层发送一些原始数据,处理很长时间,然后发回一些数据(例如,最小的编组开销)。 如果您的算法需要跨 C++/CLI 层进行更广泛的交互,那么它会变得更加棘手。
“全 C#”或“全托管”的好处是 (1) 跳过此编组层(这是开销,有时根据工作的不同很乏味),以及 (2) .NET 引擎可以进行的运行时优化对于运行代码的特定计算机(本机 C/C++ 和非托管代码都无法做到这一点)。
我同意此线程中的其他评论,即您应该/必须用您的场景“测试”它。 具有性能敏感转换的“大”C++/CLI 层很难做到,因为当您不断在托管/非托管之间跳转时(自动)会发生“装箱/拆箱”。
最后,混合“托管/非托管”设计与“全托管”设计之间的
最终性能差异与以下方面的权衡有关:.NET 引擎能否对 .NET 代码进行特定于机器的优化(例如,利用特定于机器的线程/核心/寄存器),比“纯本机”代码(链接到混合模式程序集)能够通过绕过 .NET 引擎(这是一个翻译)? 确实,编写良好的本机代码可以“检测”处理器线程,但通常无法检测特定于机器的寄存器(除非针对该目标平台进行编译)。 相比之下,本机代码没有通过 .NET 运行时的“开销”,它只是一个虚拟机(可以通过将某些逻辑即时编译到其特定的底层硬件来“加速”)。
复杂的问题。 对不起。 恕我直言,如果“性能敏感”是您的问题,那么此类问题没有简单的答案。