哪个更快 - C#不安全代码或原始C ++

时间:2008-11-11 11:05:51

标签: c# c++ performance image-processing unsafe

我正在编写一个图像处理程序来执行视频帧的实时处理。它是在C#中使用包装OpenCV库dll(非托管C ++)的Emgu.CV库(C#)。现在我必须编写自己的特殊算法,它需要尽可能快。

哪种算法的实施速度更快?

  1. 在C#中编写'不安全'功能

  2. 将功能添加到OpenCV库并通过Emgu.CV调用

  3. 我猜C#unsafe速度较慢,因为它通过了JIT编译器,但区别是否显着?

    编辑:

    在VS2008下为.NET 3.5编译

10 个答案:

答案 0 :(得分:67)

它需要尽快

然后你问的是错误的问题。

使用汇编程序对其进行编码,为您支持的每个重要架构变体使用不同的版本。

使用优秀的C ++编译器的输出作为指导,因为它可能知道一些你不知道的技巧。但是你可能会想到一些改进,因为C ++并不一定向编译器传达可能对优化有用的所有信息。例如,C ++没有C99关键字限制。虽然在这种特殊情况下,许多C ++编译器(包括MSVC)现在支持它,但请尽可能使用它。

当然,如果你的意思是“我希望它快速,但不要超出C#或C ++之外”,那么答案是不同的; - )

在很多情况下,我希望C#至少能够达到类似外观的C ++的性能。我当然假设程序运行的时间足够长,以至于JIT本身所用的时间是无关紧要的,但是如果你正在处理很多视频,那么这似乎很可能。但是我也希望有一些东西,如果你在不安全的C#中执行它们,将远远慢于C ++中的等价物。我不知道它们是什么,因为我对JIT的所有经验都是用Java而不是CLR。在C ++中也可能存在速度较慢的事情,例如,如果您的算法将任何调用重新调回C#代码。

不幸的是,确定它的接近程度的唯一方法是编写它们并测试它们,哪种方式错过了编写C ++版本需要付出额外努力的重点。但是,您可能会通过黑客攻击一些近似于您想要执行的处理的快速代码来获得一个粗略的想法,而不必完成所有操作或正确处理。如果算法要遍历所有像素并且每个像素执行一些FP操作,那么将粗略的基准测试混合在一起需要花费半个小时。

通常我会建议不要开始思考“这需要尽可能快”。要求应该是可以实现的,并且根据定义“尽可能X”只能实现边界化。要求也应该是可测试的,并且“尽可能的X”是不可测试的,除非您以某种方式知道理论最大值。一个更友好的要求是“这需要在如此速度的CPU上实时处理这种分辨率的视频帧”,或者“这需要比我们的主要竞争对手的产品更快”。如果C#版本可以做到这一点,有一点需要考虑用户设置中的意外小问题,那么就完成了工作。

答案 1 :(得分:6)

这取决于算法,实现,C ++编译器和JIT编译器。我猜在大多数情况下C ++实现会更快。但这可能会改变。

JIT编译器可以针对运行代码的平台优化代码,而不是像C ++编译器那样对代码可能运行的所有平台的平均代码进行优化。这是JIT编译器的新版本越来越擅长并且在某些情况下可能给JITted代码带来优势。所以答案并不像你想象的那么清楚。例如,新的Java热点编译器非常好。

托管代码可能比C ++做得更好的其他情况是需要分配和释放大量小对象的地方。 .net运行时预先分配了大块可以重用的内存,因此每次需要分配内存时都不需要调用os。

我不确定不安全的C#运行速度比普通C#快得多。你也必须尝试这个。

如果您想知道什么是适合您情况的最佳解决方案,您必须同时尝试并测量差异。我认为不会超过

答案 2 :(得分:6)

C#通常比C ++慢。托管代码中存在运行时检查。毕竟,这些是使它得到管理的原因。例如,C ++不必检查是否已超出数组的边界。

根据我的经验,使用固定内存有很大帮助。 .NET 4.0中有一个新的System.IO.UnmanagedMemoryAccessor类,可能在将来有所帮助。

答案 3 :(得分:5)

语言没有“速度”。这取决于编译器和代码。用任何语言编写效率低下的代码是可能的,无论源语言如何,聪明的编译器都会生成接近最优的代码。

C#和C ++之间唯一真正不可避免的性能因素是C#应用程序必须在启动时做更多事情(加载.NET框架并且可能JIT一些代码),所以在所有条件相同的情况下,它们的启动速度会慢一些。在那之后,它取决于,并且没有一个根本原因,为什么一种语言必须总是比另一种语言更快。

我也不知道为什么不安全的C#应该比安全更快。一般来说,安全性很好,因为它允许编译器做出更强大的假设,因此安全可能更快。但同样,这取决于您正在编译的代码,您正在使用的编译器以及其他十几个因素。

简而言之,放弃你可以衡量一种语言表现的想法。你不能。语言永远不会“快”或慢“。它没有速度。

答案 4 :(得分:4)

如果您要以标准方式实现算法,我认为这是无关紧要的。 但是有些语言绑定到api或库,可以给你一个非标准的提升。

  1. 考虑一下你是否可以使用GPU处理 - nvidia和ati提供CUDA和CTM框架,并且khronos组(openGL)正在进行标准化工作。预感告诉我,amd将在未来的芯片中添加至少一个流处理器核心。所以我认为在这方面有很大的希望。

  2. 试着看看你是否可以利用SSE指令,C ++或C-中的库都提供了方便的api,请查看英特尔的网站以获得方便的优化库我记得“Intel Performance Primitives”和“数学核心“。

  3. 但在政治方面,请将您的算法纳入OpenCV,以便其他人也可以从中受益。

答案 5 :(得分:3)

这场战斗将永远肆虐。 C与C ++与C#相比。 在C#中,不安全的概念是解锁“危险”操作。即,使用指针,并能够转换为void指针等,就像在C和C ++中一样。 非常危险,而且非常强大!但是要击败C#的基础。

你会发现,如今,微软在性能方面取得了长足进步,特别是自.NET发布以来,下一版本的.NET实际上将支持内联方法,就像使用C ++一样。这将在特定情况下提高性能。我讨厌它不会成为一个c#特性,而是编译器选择的一个讨厌的属性 - 但是你无法拥有它。

就个人而言,我正在用C#编写一个游戏并管理DirectX(为什么不是XNA?超出了本文的范围)。我在图形情境中使用不安全的代码,这导致了对其他人所说的方向的点头。

这只是因为GDI ++的像素访问速度非常慢,我被驱使寻找替代方案。但总的来说,c#编译器非常好,而且对于代码比较(你可以找到文章),你会发现性能与c ++非常相似。 这并不是说没有更好的方法来编写代码。

在一天结束时,我个人认为C,C ++和C#在执行时的速度大致相同。只是在一些痛苦的情况下,你想要与底层硬件密切合作或非常接近这些像素,你会发现C / C ++人群有明显的优势。

但对于商业和现在的大多数事情来说,C#是一个真正的竞争者,并且保持在“安全”的环境中绝对是一个奖励。
走出去的时候,你可以用不安全的代码完成大部分工作,就像我一样 - 而且男孩,我已经走到了极端!但它值得吗?可能不是。我个人想知道我是否应该更多地考虑C ++中的时间关键代码,以及C#中所有面向对象的安全内容。但是我的表现比我想象的要好!

只要您对所制作的互操作电话数量非常小心,您就可以充分利用这两个世界。我个人避免这样做,但我不知道要花多少钱。

这是一种我没有尝试过的方法,但是很想听到冒险,实际上使用C ++ .NET来开发一个库 - 这会比c#对这些特殊图形情况不安全吗?与本机C ++编译代码相比如何?现在有一个问题!

嗯..

答案 6 :(得分:2)

如果你了解你的环境并使用一个好的编译器(对于Windows上的视频处理,英特尔C ++编译器可能是最好的选择),C ++将击败C#,有几个原因:

  • C ++运行时环境没有内在的运行时检查(缺点是你可以自由地统治自己)。 C#运行时环境将进行一些健全性检查,至少在最初阶段。
  • C ++编译器是为优化代码而构建的。虽然理论上可以使用ICC(或GCC)使用的所有优化voodo来实现C#JIT编译器,但是微软的JIT可靠地做得更好是值得怀疑的。即使JIT编译器具有运行时统计信息,这仍然不如ICC或GCC中的配置文件引导优化那么好。
  • C ++环境允许您更好地控制内存模型。如果您的应用程序达到了破坏数据缓存或分割堆的程度,那么您将非常感谢对分配的额外控制。哎呀,如果你可以避免动态分配,你已经好多了(提示:malloc()或任何其他动态分配器的运行时间是不确定的,并且几乎所有非本地语言都会强制使用更多的堆,因此更重的分配)。

如果您使用的是较差的编译器,或者您无法定位好的芯片组,所有投注均已关闭

答案 7 :(得分:1)

我的回复有点迟,但我可以给你一些轶事经验。我们有一些矩阵乘法例程,最初使用指针和不安全代码在C#中编码。这被证明是我们应用程序中的瓶颈,然后我们使用pinning + P / Invoke来调用Matrix乘法例程的C ++版本,并获得了2倍的改进。这是很久以前的.NET 1.1,所以现在情况可能会好一些。正如其他人指出的那样,这个证明没什么,但这是一个有趣的练习。

我也同意thAAAnos,如果算法真的必须“尽可能快”利用IPL,或者,如果必须,考虑GPU实现。

答案 8 :(得分:1)

老实说,你用它编写的语言并不像你使用的算法那么重要(IMO,无论如何)。也许通过转到本机代码,你可能使你的应用程序更快,但它也可能使它变慢 - 它取决于编译器,程序如何编写,你需要什么样的互操作成本'如果您使用的是混合环境等,则会产生影响。如果不对其进行分析,您无法说出来。 (并且,就此而言,你有没有想过你的申请?你真的知道它花在哪里吗?

更好的算法完全独立于您选择的语言。

答案 9 :(得分:-7)

在CPU上运行总是比在CPU上运行VM更快。我无法相信人们会试图反驳。

例如,我们在排队的网络服务器上进行了一些相当繁重的图像处理工作。最初为了让它工作,我们使用了PHP的GD功能。

他们很慢。我们重写了C ++中所需的功能。

相关问题