C++ 将Matlab加速到C++;转化

C++ 将Matlab加速到C++;转化,c++,performance,matlab,image-processing,C++,Performance,Matlab,Image Processing,我有一些Matlab图像处理代码,运行速度非常慢,我准备将其转换为C/C++。我对matlab的工作原理和代码的执行方式不太了解,但我只是想听听我期望的加速效果。显然,有很多变量会影响这一点,但我只是想从你自己的经验中寻找一个指南 谢谢 Zenna这实际上取决于Matlab代码的质量以及您正在做的事情。由Matlab专家编写的惯用Matlab代码将很难被击败,特别是如果你不是一个优化大师,并且纯粹希望由于语言的转换而加快速度的话。例如,我发现即使是一些比较著名的基于C的FFT库也无法与Matla

我有一些Matlab图像处理代码,运行速度非常慢,我准备将其转换为C/C++。我对matlab的工作原理和代码的执行方式不太了解,但我只是想听听我期望的加速效果。显然,有很多变量会影响这一点,但我只是想从你自己的经验中寻找一个指南

谢谢


Zenna

这实际上取决于Matlab代码的质量以及您正在做的事情。由Matlab专家编写的惯用Matlab代码将很难被击败,特别是如果你不是一个优化大师,并且纯粹希望由于语言的转换而加快速度的话。例如,我发现即使是一些比较著名的基于C的FFT库也无法与Matlab的FFT相媲美


<>这是说,把一个写得很差的MATLAB程序和一个平均写的C++程序进行比较,我想说你在我的经验中看到了一个数量级。p> 对于你可能获得何种加速的问题,简短的回答是“视情况而定”

Matlab是一个解释器,所以总体上比本地C++代码慢得多。然而,许多matlab函数都经过了很好的优化,最近的版本包括JIT。因此,您必须决定是用C语言重写所有matlab代码,还是只重写关键部分,还是优化matlab代码本身以使其运行更快


我建议您首先使用Matlab的内置评测工具来查找应用程序中的性能瓶颈。在这种情况下,您可以调整matlab代码以获得更好的性能。经验法则是通过使用矢量化数组操作来避免循环,而不是一次迭代一个元素。

例如,matlab使用FFTW库来实现fft算法。那座图书馆的性能几乎无与伦比。据我所知,唯一可比的是英特尔数学内核库(MKL),但它是商用的。所以首先,我建议使用你们能找到的所有数学图书馆。Matlab正在幕后做这件事

的确,有时很难打败matlab。但问题是matlab profiler并不总是提供足够的关于如何改进代码的信息。您知道一些matlab方法占用了大部分时间,但您并不总是知道这些方法是否可以通过另一种方式调用它们来提高性能,因为该方法是一个黑盒

在C/C++中,您有这样的工具,允许您检查编译器生成的汇编程序,这样您就可以帮助编译器改进代码内联方法,例如。但同样,matlab在幕后使用专业的数学库,如果在执行matlab代码时大部分时间都花在这些库上,那么性能很难提高


我希望你能尝试一种不同的方法。您可以使用matlab profiler分析瓶颈,看看是否值得将代码迁移到本机代码。Matlab允许您这样做。你也可以反过来做。您可以在C/C++中实现一些胶水,并调用matlab进行一些操作,因为您的本地代码比matlab慢

对于图像处理,您可以获得明显的加速。但这实际上取决于您编写MATLAB代码的能力。很多事情都可以矢量化或由内置函数处理。这类代码的速度非常快

然而,如果你发现你的代码由很多循环组成(比如说,在一幅图像中的所有像素上循环),那么它的速度会非常慢,矢量化可以提供100倍或更多的加速

如果您的代码在MATLAB中很难做到“正确”,那么切换到C是一个可行的选择。我在学校做了一个计算机视觉项目(3D点重建),它清楚地表明了这一点。当我们的项目在C++和OpenCV中实现时,其他项目中的一个甚至还没有加载图像。它们是用MATLAB编写的。我们从未计时,但我猜我们的版本运行速度快了10倍左右


但话说回来,他们的MATLAB代码可能根本没有经过优化。因此,它并不是真正有用的基准。

它主要取决于Matlab中循环的紧密性。如果只是调用一系列内置的Matlab图像处理函数,则很可能无法提高性能(很可能会影响性能)。如果您正在循环图像像素或进行某种块处理,您可能会看到很大的改进。如果您正在做一些循环,但是每次迭代中的处理量很大,那么您可能只看到很少或没有改进

我看Matlab的方式是,每个执行的行都有一些开销。如果你能将你的解转化为矩阵乘法,或者其他向量/矩阵运算的形式,你只会遭受一次这样的开销,这是可以忽略不计的。但是,对于循环,每次循环迭代时都会产生这种开销。此外,大多数Matlab的图像处理函数只是调用优化的库,所以不要尝试重新创建它们,除非您确实知道它们可以改进的地方

我发现最好的方法是使用C和Matlab的组合。我使用Matlab时,运算可以很容易地矢量化(放在向量/矩阵运算方面)。这可能意味着从一个不同的角度来解决问题,而不是从一个看起来最简单的角度来解决问题。此外,很难打败Matlab的绘图和可视化功能,因此我绝对不会使用全C/C++解决方案,除非您有一个如何使用C/C++显示的计划(如果这是您项目的一部分)

如果我不能想出一个相对简单的矢量化方法,我只需要在一个可以从Matlab调用的cmex函数中实现需要紧循环的处理部分。我