English 中文(简体)
哪个更快- C #不安全代码还是原始C ++?
原标题:
  • 时间:2008-11-11 11:05:51
  •  标签:

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

哪种实现方式会更快地执行算法?

  1. 在C#中编写一个不安全的函数

  2. 将该功能添加到OpenCV库中,并通过Emgu.CV进行调用。

我猜测C#的unsafe较慢,因为它需要通过JIT编译器,但是差别会很明显吗?

编辑:

在VS2008下为.NET 3.5编译

最佳回答

它需要尽可能快。

那你问错问题了。

使用汇编语言编码,并针对您支持的每个重要的架构变体创建不同的版本。

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

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

我希望 C# 在很多情况下至少能接近类似的 C++ 的性能。我当然假定程序运行的时间足够长,JIT 本身需要的时间是无关紧要的,但如果你正在处理大量的视频,则似乎很可能。但我也希望有些事情,如果你在不安全的 C# 中执行它们,将比在 C++ 中等效的事情要慢得多。我不知道它们是什么,因为我所有关于 JIT 的经验都是在 Java 而不是 CLR 中。也可能有些事情在 C++ 中会更慢,例如,如果您的算法对 C# 代码进行任何回调。

不幸的是,确保它们多接近的唯一方法是编写两个版本并测试它们,这有点违背了写C++版本需要额外努力的初衷。但是,您可以通过黑客一些快速代码来近似处理您想要执行的处理,而不必执行全部或正确。如果您的算法将循环遍历所有像素并对每个像素执行少数FP运算,则拼凑一个大致的基准测试应该只需要半个小时。

通常我会建议不要开始思考“这需要尽可能快”。需求应该是可以实现的,而且“尽可能X”只是边缘可实现的。需求也应该是可测试的,“尽可能X”除非你知道一个理论上的极限,否则是不可测试的。更友好的要求是“这需要在这样的速度CPU上实时处理某分辨率的视频帧”,或者“这需要比我们主要竞争对手的产品更快”。如果C#版本可以达到这样的要求,并留有一点余地来考虑用户设定中意外的小问题,那么工作完成了。

问题回答

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

JIT 编译器可以针对您的代码运行的平台进行优化,而不是像 C++ 编译器那样为您的代码可能运行的所有平台平均优化。这是 JIT 编译器的新版本越来越擅长的事情,在某些情况下可能使 JIT 的代码具有优势。所以答案并不像您想象的那样明确。例如,新的 Java 热点编译器就做得非常好。

受控代码优于 C++ 的其他情况是需要分配和释放大量小对象的情况。.net runtime 预分配大块可重复使用的内存,因此在需要分配内存时不必每次都调用操作系统。

我不确定不安全的C#是否比普通的C#运行得更快。你也需要尝试一下。

如果你想知道你的情况的最佳解决方案,你需要尝试两种方式并且对比测量它们的差异。我认为不会有更多的。

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

C#和C++之间性能上唯一无法避免的因素就是C#应用程序在启动时必须执行更多操作(加载.NET框架,或许还需要即时编译一些代码),因此所有条件相同的情况下,它们的启动速度会稍慢一些。之后,这取决于具体情况,没有根本性的理由表明为什么一种语言必须永远比另一种语言快。

我也不知道不安全的 C# 为什么会比安全的更快。一般来说,安全是好的,因为它让编译器能够做出更强的假设,所以安全可能更快。但是,这还取决于你正在编译的代码、你正在使用的编译器以及其他十几个因素。

简言之,放弃认为你可以测量一种语言的表现的想法。你不能。一种语言从来没有“快”或“慢”这样的速度。它没有速度。

C#通常比C++慢。托管代码中有运行时检查。毕竟这就是它被托管的原因。例如,C++不必检查数组边界是否超出限制。

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

If you are going to implement your algorithm in a standard way I think it s irrelevant. But some languages have bindings to apis or libraries that can give you a non standart boost.

  1. 考虑是否可以使用GPU处理- Nvidia和ATI提供CUDA和CTM框架,并且khronos组织(OpenGL)正在进行标准化努力。我的直觉告诉我,AMD将在其未来芯片中添加至少一个流处理器核心。因此,我认为这方面有相当大的前景。

  2. 试图查看是否可以利用SSE指令,有一些库可用-大多数是使用C ++或C编写,提供方便的API,请检查英特尔网站以获取方便的优化库,我记得有“英特尔性能原语”和“Math Kernel”。

但在政治方面,请将您的算法整合到OpenCV中,以便其他人也可以受益。

It s a battle that will rage on forever. C versus C++ versus C# versus whatever. In C#, the notion of unsafe is to unlock "dangerous" operations. ie, the use of pointers, and being able to cast to void pointers etc, as you can in C and C++. Very dangerous, and very powerful! But defeating what C# was based upon.

你会发现,现在微软在性能方面取得了长足的进步,特别是自.NET发布以来,而下一个版本的.NET实际上将支持内联方法,就像C++一样。这将增加特定情况下的性能。我讨厌这不是c#的特性,而是编译器检测到的讨厌属性-但你不能拥有一切。

就我个人而言,我正在使用C#和托管的DirectX编写游戏(为什么不用XNA?? 超出了这篇文章的范围)。在图形情况下,我正在使用不安全的代码,这说明了其他人所说的方向。

It s only because pixel access is rediculously slow with GDI++ that I was driven to look for alternatives. But on the whole, the c# compiler is pretty damned good, and for code comparisons (you can find articles) you ll find the performance is very comparable to c++. That s not to say there isn t a better way to write the code.

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

But for business, and most things nowadays, C# is a real contender, and staying within the "safe" environment is definitely a bonus.
When stepping outside, you can get most things done with unsafe code, as I have - and boy, have I gone to some extremes! But was it worth it? Probably not. I personally wonder if I should have thought more along the lines of time-critical code in C++, and all the Object Oriented safe stuff in C#. But I have better performance than I thought I d get!

只要您小心处理Interop调用的数量,就可以同时享受两个世界的好处。我个人已经避免了这种情况,但我不知道代价是多少。

我尚未尝试的一种方法,但我很想听听体验,实际上是使用C++.NET开发库-这是否比c#的不安全对于这些特殊的图形情况更快?与本机C++编译代码相比如何?现在有个问题!

嗯。。

如果你了解你的环境并使用一个优秀的编译器(对于在Windows上的视频处理,Intel C++编译器可能是最佳选择),C++会在几个方面完胜C#:

  • The C++ runtime environment has no intrinsic runtime checks (the downside being that you have free reign to blow yourself up). The C# runtime environment is going to have some sanity checking going on, at least initially.
  • C++ compilers are built for optimizing code. While it s theoretically possible to implement a C# JIT compiler using all of the optimizing voodo that ICC (or GCC) uses, it s doubtful that Microsoft s JIT will reliably do better. Even if the JIT compiler has runtime statistics, that s still not as good as profile-guided optimization in either ICC or GCC.
  • A C++ environment allows you to control your memory model much better. If your application gets to the point of thrashing the data cache or fragmenting the heap, you ll really appreciate the extra control over allocation. Heck, if you can avoid dynamic allocations, you re already much better off (hint: the running time of malloc() or any other dynamic allocator is nondeterministic, and almost all non-native languages force heavier heap usage, and thus heavier allocation).

如果您使用不良的编译器,或者无法定位良好的芯片组,那么一切皆不确定

老实说,你用哪种语言写并不是非常重要,最重要的是你使用什么算法(在我看来)。也许通过转换成本地代码,你可以使你的应用程序更快,但也可能使它变慢——这取决于编译器,程序的编写方式,如果你使用混合环境会产生什么样的互操作成本等等。你不可以没有分析就下定论。(另外,你有对你的应用程序进行分析吗?你真的知道它在哪里消耗时间吗?)

一个更好的算法与你选择的语言完全无关。

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

我也同意thAAAnos的观点,如果你的算法确实需要“尽可能快”,则应利用IPL,或者如果必须的话,考虑GPU实现。





相关问题
热门标签