加速Matlab到C ++的转换

时间:2009-08-04 21:41:44

标签: c++ performance matlab image-processing

我有一些Matlab图像处理代码运行得非常慢,我准备将其转换为C / C ++。我真的不太了解matlab如何工作以及如何执行代码,但我只是想知道我可能期望的加速类型。很明显,有许多变量会影响到这一点,但我只是想根据你自己的经验寻找指南。

由于

泽纳

7 个答案:

答案 0 :(得分:8)

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

我看待Matlab的方式是每个执行的行都有一些开销。如果您可以将解决方案放入矩阵乘法或其他向量/矩阵运算的形式,那么您只需承受一次开销,并且可以忽略不计。但是,对于循环,每次循环迭代时都会遭受这种开销。此外,Matlab的大多数图像处理功能只是调用优化库,因此除非您确定可以在何处进行改进,否则不要尝试重新创建它们。

我发现最好的方法是使用C和Matlab的组合。当操作可以很容易地进行矢量化时(使用矢量/矩阵操作),我使用Matlab。这可能意味着从一个看起来最直接的角度来解决问题。此外,很难击败Matlab的绘图和可视化,所以我绝对不会转向所有的C / C ++解决方案,除非你有一个如何使用C / C ++进行展示的计划(如果这是你项目的一部分)。

如果我无法想出一种相对简单的矢量化方法,我只需要在可以从Matlab调用的C mex函数中实现需要紧密循环的处理部分。在这种情况下,我倾向于使用C而不是C ++,因为该过程应该相对较小并且不需要大量复杂的数据抽象,但C ++也可以正常工作。确保以列为主要顺序访问图像数据以最大化缓存命中率,因为这是Matlab组织其矩阵的方式。

答案 1 :(得分:4)

这实际上取决于您的Matlab代码的质量以及您正在做的事情。由Matlab专家编写的惯用语Matlab代码将很难被击败,特别是如果你不是一个优化专家并且纯粹期望由于语言的转换而加速。例如,我发现甚至一些比较好的基于C的FFT库与Matlab的FFT不匹配。

也就是说,将写得不好的Matlab程序与平均编写的c ++程序进行比较,我会说你的经验看起来是一个数量级。

答案 2 :(得分:3)

关于你可能获得什么样的加速的问题的简短答案是“它取决于”。

Matlab是一个解释器,所以整体来说它比本机c ++代码要慢得多。但是,许多matlab函数都经过了很好的优化,最近的版本包括JIT。所以你必须决定是否用C语言重写所有matlab代码,只重写关键部分,或者优化matlab代码本身以便更快地运行。

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

答案 3 :(得分:1)

例如,matlab使用FFTW库来实现fft算法。该库的性能几乎不可能被击败。我所知道的唯一可比较的是intel Math Kernel Library(MKL),但它是商业的。所以首先我建议你使用你能找到的每一个数学图书。 Matlab正在幕后做这件事。

有时候很难击败matlab。但问题是matlab探查器并不总能为您提供有关如何改进代码的足够信息。你知道有些matlab方法占用大部分时间,但你并不总是知道是否有提高性能的方法以另一种方式调用它们,因为该方法是一个黑盒子。

在C / C ++中,你有像valgirnd这样的工具,它们允许你检查编译器正在生成的汇编器,以及你可以帮助编译器改进代码内联方法的代码。但是,matlab再次在幕后使用专业的数学库,如果在执行matlab代码时大部分时间花在这些库上,那么性能很难提高。

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

答案 4 :(得分:1)

对于图像处理,您可以获得显着的加速。但这实际上取决于你编写MATLAB代码有多好。许多东西可以通过内置函数进行矢量化或处理。这种代码非常快。

但是,如果你发现你的代码包含很多循环(例如,循环遍历图像中的所有像素),它将会非常慢,矢量化可以提供100倍或更多的速度。

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

但话说回来,他们的MATLAB代码可能根本没有优化。所以它作为基准测试并不是很有用。

答案 5 :(得分:1)

我在c ++中导出了一个matlab例程,并使用visual studio c ++编译为mex。加速是10的因素。如果我使用多核,那么我的速度也可能提高3倍。

如果你在斜坡上有坡度并且对矩阵的单个组成部分做了某些事情,比如y(m,n)= x(m)* a - x(m-1)那么对于斜率你会加快速度。

如果你使用很多matlab函数进行计算,那么matlab函数本身会做很多操作,那么用c ++导出代码就没什么意义了。

答案 6 :(得分:0)

正如其他人所说,使用MATLAB分析器来查看瓶颈是什么。如果它是矩阵数字运算,你有一个很高的标准来跳过MATLAB。如果您有很多条件语句或函数调用,那么您更有可能提高速度。

确保尽量减少在MATLAB和C ++之间传输数据的次数。如果要在一个大块中发送大型数据阵列,则可能很快。否则,如果您来回进行大量数据传输,即使您的C ++程序速度很快,也可能会失去数据转换的速度优势。

我还会查看您的算法并考虑使用Java。从MATLAB调用自定义Java代码非常方便,因为MATLAB已经在JRE上运行。在MATLAB函数和我的自定义Java代码之间传输大数据数组的速度给我留下了非常深刻的印象。几年前我曾用直接C ++(使用MEX或其他)来实现一种算法来加速MATLAB,它只是处理所有数据结构的噩梦。我最终使用的是COM / ActiveX,因为我在Windows机器上运行并且接口更容易。

在完成大量低级编程以解决数值问题之后,我对可能出现的问题有了更好的认识,从数值精度到编程维护问题,除非有巨大的性能优势,否则我会选择比C / C ++更高级的语言。