C++ CLI.本机部分是用纯C++编写的,但是在CLI中编译的速度和纯本机C++一样快?

Ste*_*and 14 c++ c++-cli

我想将音频计算委托给C++层,但是通过WPF GUI处理和编辑音频内容.

我简要介绍了C++/CLI,我想知道:

  • 我应该使用C++/CLI作为C#GUI和C++音频管理之间的中间层
  • 或者我应该简单地将我的代码放在C++/CLI中并期望它以相同的方式编译,因此效率很高.

编辑:随着火焰战可能开始.这是一个关于基准游戏的链接,它明确指出C/C++是速度获胜者.我在问:我应该在C++ Dll或C++ CLI程序集中编写C++.

Ben*_*igt 25

在C++/CLI中,托管类型(ref class例如)及其成员编译为MSIL.这意味着不使用SIMD,更不用说优化了(至少在当前版本的.NET中,微软给出的理由不会很快改变,尽管他们可以改变他们对权衡的评估).

另一方面,本机类型可以编译为MSIL或本机机器代码.虽然Visual C++没有世界上最好的C++优化器,但它非常好.所以我的建议是编译为本机代码.在托管代码和本机代码之间调用时,Visual C++将使用C++互操作,这非常有效(它与internalcall所有.NET的内置函数(如字符串连接)使用的技术相同).

为了实现这一点,您可以将时间关键代码放在单独的目标文件中(不是单独的DLL!,让链接器将托管代码和非托管代码组合成一个"混合模式"程序集),而不是编译/clr,或者将其括起来#pragma managed(push, off)... #pragma managed(pop).无论哪种方式都可以获得最大程度的优化,并允许您使用SIMD内在函数来实现非常快速的代码.

  • @Stephane:请注意,通过p/invoke调用本机DLL比在混合模式DLL中使用C++ interop慢得多.如果您对所使用的类型非常小心(例如,避免使用ANSI字符串,因为它们将永远转换为.NET的Unicode表示形式),您可以将此成本降至最低, (5认同)

cha*_*ley 5

桥接C ++ / CLI层是一种编组工作,其中将托管状态转换为原始类型,以编组到非托管层,进行处理,然后编组回去。根据您的算法(以及用于“包装”该过渡层的实用程序),最好使编组尽可能有限(较小)。

因此,这取决于问题:最简单的问题是一个接口,该接口在C ++ / CLI层上发送一些原始数据,处理很长一段时间,然后再发送一些数据(例如,最小的编组开销)。如果您的算法需要在C ++ / CLI层之间进行更广泛的交互,那么它将变得非常棘手。

“ All C#”或“ All Managed”的好处是(1)跳过此编组层(这是开销,根据工作有时会很乏味),以及(2).NET引擎可以进行的运行时优化运行代码的特定计算机(本机C / C ++不能运行,非托管代码也不能运行)。

我同意该线程中的其他评论,即您应该/必须对自己的方案进行“测试”。具有性能敏感转换的“大” C ++ / CLI层很难做到,因为当您在受管理/不受管理之间进行切换时(自动)发生“装箱/拆箱”。

最后,混合“托管/非托管”设计与“全托管”设计之间的最终性能差异与以下因素之间的权衡取舍:.NET引擎能否对.NET代码进行机器特定的优化(例如,利用特定于机器的线程/核心/寄存器的优势,大于“纯本机”代码(链接到混合模式程序集)能够绕过.NET引擎(是解释器)来处理FAST?

正确编写的真实本机代码可以“检测”处理器线程,但通常无法检测到计算机专用的寄存器(除非针对该目标平台进行了编译)。相比之下,本机代码没有经过.NET运行时的“开销”,后者只是一个虚拟机(可以通过对特定逻辑基础硬件进行即时编译来“加速”该虚拟机)。

复杂的问题。抱歉。恕我直言,如果“性能敏感”是您的问题,那么对于这种类型的问题就没有简单的答案。

  • 您为什么认为在执行过程中无法编写c和c ++来进行优化?还是在运行时检测CPU功能(例如寄存器或SSE)?这一直都在做。.NET不是魔术。只是好奇。 (2认同)