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

时间:2011-04-17 12:22:21

标签: c++ c++-cli

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

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

  • 我应该使用C ++ / CLI作为C#GUI和C ++音频管理之间的中间层
  • 或者我应该简单地将我的代码放在C ++ / CLI中,并期望它以相同的方式编译,因此效率很高。
编辑:随着火焰战可能开始。 这是一个链接到benchmarks game,它清楚地表明C / C ++是速度获胜者。 我在问:我应该在C ++ Dll或C ++ CLI程序集中编写C ++。

4 个答案:

答案 0 :(得分:23)

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

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

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

答案 1 :(得分:4)

桥接C ++ / CLI层是一种编组工作,其中托管状态转换为基本类型,以编组到非托管图层,进行处理,然后进行编组。根据您的算法(以及“包装”过渡层的语用学),最好将编组保持为有限(小)。

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

“所有C#”或“全部管理”的好处是(1)跳过此编组层(这是开销,有时单调乏味取决于工作),以及(2).NET引擎的运行时优化可以为运行代码的特定计算机(使用本机C / C ++,也不能使用非托管代码)。

我同意这个帖子中的其他评论,你应该/必须用你的场景“测试”它。具有性能敏感转换的“大”C ++ / CLI层很难做到,因为当你在托管/非托管之间不断跳跃时(自动)发生“装箱/拆箱”。

最后,混合“托管/非托管”设计与“全托管”设计之间的最终性能差异与以下两者之间的权衡有关:.NET引擎能否使机器特定.NET代码的优化(例如,利用机器特定的线程/核心/寄存器),比“纯本机”代码(链接到混合模式程序集)更大,能够通过绕过.NET引擎(解释器)?

确实,编写良好的本机代码可以“检测”处理器线程,但通常无法检测特定于机器的寄存器(除非针对该目标平台进行了编译)。相比之下,本机代码没有通过.NET运行时的“开销”,.NET运行时只是一个虚拟机(可以通过实时编译某些逻辑到其特定的底层硬件来“加速”)。

复杂的问题。抱歉。恕我直言,如果“性能敏感”是你的问题,对这类问题没有简单的答案。

答案 2 :(得分:2)

我建议你看看this article。此外,在尝试确定最适合编写代码的内容时,您应该(总是)对您的案例进行一次小测试,看看您遇到的具体情况是否有任何差异。

答案 3 :(得分:-7)

从我自己的测试中我完成了主题C#比原生C ++算法更快。唯一的缺点是C#和C ++在互联网上的算法较少。

相关问题