代码之家  ›  专栏  ›  技术社区  ›  geometrikal

哪个是更快的——C不安全代码或原始C++

  •  23
  • geometrikal  · 技术社区  · 16 年前

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

    哪一种算法可以更快地实现?

    1. 在C中编写“不安全”函数#

    2. 将函数添加到opencv库并通过emgu.cv调用它

    我猜C unsafe会慢一些,因为它会通过JIT编译器,但是差异会有意义吗?

    编辑:

    根据VS2008为.NET 3.5编译

    10 回复  |  直到 10 年前
        1
  •  67
  •   Steve Jessop    15 年前

    它需要尽可能快

    然后你问错了问题。

    在汇编程序中编写代码,为您支持的每个重要体系结构变体提供不同的版本。

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

    当然,如果你的意思是,“我希望它是快的,但不是到C C或C++之外的程度”,那么答案是不同的;

    在很多情况下,我希望C语言至少能达到类似C++的性能。当然,我假设程序运行的时间足够长,以至于JIT本身所花费的时间是不相关的,但是如果您处理的视频太多,那么这似乎是可能的。但我也希望有一些事情,如果你在不安全的C语言中做的话,将会比C++中的等价物慢得多。我不知道它们是什么,因为我所有的JIT经验都是Java而不是CLR。也可能有些事情在C++中比较慢,例如,如果你的算法把任何调用回C代码。

    不幸的是,唯一确定的方法是写和测试它们,这忽略了编写C++版本是一大堆额外的努力。然而,您可能可以通过黑客一些快速代码来获得一个大致的想法,这些代码近似于您想要做的处理,而不必做所有的事情或使其正确。如果你的算法要在所有像素上循环,并在每个像素上做一些fp操作,那么一个粗略的基准测试需要花费半个小时的时间。

    通常我会建议不要开始思考“这需要尽可能快”。需求应该是可实现的,并且根据定义,“尽可能地x”只是可实现的边界。需求也应该是可测试的,“尽可能地x”是不可测试的,除非你知道理论上的最大值。一个更友好的要求是“这需要在这样一个高速的CPU上实时处理这样和这样的分辨率的视频帧”,或者“这需要比我们的主要竞争对手的产品更快”。如果C版本做到了这一点,在用户设置中有一点多余的空间来解决意外的小问题,那么任务就完成了。

        2
  •  6
  •   Mendelt    16 年前

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

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

    托管代码可以比C++做得更好的其他情况是需要分配和释放许多小对象的地方。.NET运行时预分配可重用的大内存块,因此不需要每次分配内存时都调用操作系统。

    我不确定不安全的C比正常的C快得多。你也得试试这个。

    如果你想知道什么是最好的解决方案来解决你的情况,你就必须同时尝试这两种方法并测量其差异。我不认为会有超过

        3
  •  6
  •   Thomas Bratt    16 年前

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

    根据我的经验,使用固定记忆有很大帮助。有一种新的 System.IO.UnmanagedMemoryAccessor .NET 4.0中的类,这可能对将来有所帮助。

        4
  •  5
  •   Stack Overflow is garbage    16 年前

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

    C和C之间的性能唯一不可回避的因素是,C应用程序在启动时必须做更多的工作(加载.NETFramework,也许JIT一些代码),所以所有的情况都一样,它们会慢一点。在那之后,就要看情况了,而且没有根本的理由解释为什么一种语言必须总是比另一种语言更快。

    我也不知道为什么不安全的C要比安全的快。一般来说,safe是很好的,因为它允许编译器做出更强有力的假设,因此是安全的。 可以 快一点。但同样,它取决于您正在编译的代码、您使用的编译器以及其他许多因素。

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

        5
  •  4
  •   thAAAnos    16 年前

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

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

    2. 试着看看你是否能利用SSE指令,在C++或C语言中有很多图书馆,提供了方便的API,检查英特尔的网站是否有便利的优化库,我记得“英特尔性能原语”和“数学内核”。

    但是在政治方面,一定要把你的算法合并到opencv中,这样其他人也会受益。

        6
  •  3
  •   Simon Miller    11 年前

    这是一场永远激战。C与C+++C=与任意。 在C中,不安全的概念是解锁“危险”操作。IE,指针的使用,以及能够抛出指针等,如你可以在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++编译代码相比,这又如何呢?现在有个问题!

    隐马尔可夫模型。。

        7
  •  2
  •   Tom Barta    16 年前

    如果你知道你的环境,并且你使用一个好的编译器(在Windows上进行视频处理,英特尔C++编译器可能是最好的选择),C++会击败C。

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

    如果你使用的编译器不好,或者你不能瞄准一个好的芯片组, 所有赌注都取消了 .

        8
  •  1
  •   Peter Tate    16 年前

    我反应有点晚,但我可以给你一些轶事经验。我们有一些矩阵乘法程序,最初是用C语言编写的,使用指针和不安全的代码。这在我们的应用中被证明是一个瓶颈,然后我们使用钉住+p/JooCK调用矩阵乘法例程的C++版本,得到了2的改进因子。这是很久以前的.NET 1.1版本,所以现在情况可能会更好。正如其他人指出的,这 证明 没什么,但这是一个有趣的练习。

    我也同意Thaaanos的观点,如果您的算法真的需要“尽可能快”地利用IPL,或者,如果必须,考虑使用GPU实现。

        9
  •  1
  •   user25967    15 年前

    老实说,你用哪种语言写它几乎没有你用哪种算法那么重要(不管怎样,IMO)。也许通过使用本机代码 可以 使您的应用程序更快,但也可能使其更慢——这取决于编译器、程序的编写方式、如果使用混合环境会产生什么样的互操作成本等等。如果不分析它,就不能真正说出来。(就此而言, 你对你的申请做了简介吗?你真的知道花在哪里吗? )

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

        10
  •  -7
  •   Dave    16 年前

    在CPU上运行总是比在CPU上的VM上运行快。我真不敢相信人们会试图以其他方式争辩。

    例如,在排队等候的Web服务器上,我们有一些相当繁重的图像处理工作。最初,为了让它正常工作,我们使用了PHP的gd函数。

    他们真是太慢了。我们重写了C++中需要的功能。