为什么我在使用MATLAB编译器时没有看到显着的加速?

时间:2008-09-26 00:02:40

标签: c performance matlab matlab-compiler

我有很多很好的MATLAB代码,运行得太慢,用C语言编写是很痛苦的。用于C的MATLAB编译器似乎没有多大帮助,如果有的话。它应该加快执行速度吗?我搞砸了吗?

11 个答案:

答案 0 :(得分:22)

如果您正在使用MATLAB complier(在最新版本的MATLAB上),那么您几乎肯定不会看到任何加速。这是因为所有编译器实际上都会为您提供一种打包代码的方法,以便将其分发给没有MATLAB的人。它不会将其转换为更快的任何东西(例如机器代码或C) - 它只是将它包装在C中,因此您可以调用它。

它通过让您的代码在MATLAB编译器运行时(MCR)上运行来实现这一点,该运行时基本上是MATLAB计算内核 - 您的代码仍在被解释。由于必须调用MCR而导致的惩罚,您可能会发现编译代码的运行速度比在MATLAB上运行它时要慢得多。

换句话说 - 你可能会说编译器实际上没有编译 - 至少在传统意义上是这样。

旧版本的编译器工作方式不同,在某些情况下可能会出现加速。对于Mathwork来说,请转到

http://www.mathworks.com/support/solutions/data/1-1ARNS.html

答案 1 :(得分:19)

根据我的经验,慢速MATLAB代码通常来自不对代码进行矢量化(即,编写for循环而不仅仅是乘法数组(简单示例))。

如果您正在进行文件I / O,请注意一次读取一个数据。查看fscanf矢量化版本的帮助文件。

不要忘记MATLAB也包含一个分析器!

答案 2 :(得分:14)

我会回应dwj所说的:如果你的MATLAB代码很慢,这可能是因为它没有足够的矢量化。如果你在对整个数组进行操作时进行显式循环,那就是罪魁祸首。

这同样适用于所有面向阵列的动态语言:Perl数据语言,数字Python,MATLAB / Octave等。在编译的C和FORTRAN编译代码中甚至是某种程度上的:特别设计的矢量化库通常都是谨慎使用的编码的内部循环和SIMD指令(例如MMX,SSE,AltiVec)。

答案 3 :(得分:5)

首先,我首先回顾有关分析和矢量化的所有上述评论。

从历史的角度来看......

旧版本的Matlab允许用户通过预解析m代码并将其转换为一组matlab库调用,将m个文件转换为mex函数。这些调用具有解释器所做的所有错误检查,但旧版本的解释器和/或在线解析器速度很慢,因此编译m文件有时会有所帮助。通常它有助于你有循环,因为Matlab很聪明,可以在C中内联其中一些。如果你有其中一个版本的Matlab,你可以尝试告诉mex脚本保存.c文件,你可以看到它的确切内容这样做。

在更新的版本中(可能是2006a及更高版本,但我不记得了),Mathworks开始为解释器使用即时编译器。实际上,这个JIT编译器自动编译所有mex函数,因此显式脱机操作根本没有帮助。在那之后的每个版本中,他们也付出了很多努力来使解释器更快。我相信更新版本的Matlab甚至不允许你自动将m文件编译为mex文件,因为它不再有意义了。

答案 4 :(得分:3)

MATLAB编译器包装你的m代码并将其发送到MATLAB运行时。因此,您在MATLAB中看到的性能应该是您在编译器中看到的性能。

根据其他答案,矢量化代码很有帮助。但是,MATLAB JIT现在相当不错,很多东西的表现大致和矢量化。这并不是说从矢量化中获得了性能上的好处,它不仅仅是曾经的神奇子弹。真正告诉的唯一方法是使用分析器来找出代码看到瓶颈的位置。通常情况下,有些地方可以进行本地重构,以真正提高代码的性能。

您可以采用其他几种硬件方法来提升性能。首先,大部分线性代数子系统都是多线程的。如果您正在使用多核或多处理器平台,则可能需要确保已在首选项中启用了该功能。其次,您可以使用并行计算工具箱来充分利用多个处理器。最后,如果您是Simulink用户,您可以使用emlmex将m代码编译为c。这对定点工作特别有效。

答案 5 :(得分:2)

您是否尝试过分析代码?您不需要对所有代码进行矢量化,只需要控制运行时间的函数。 MATLAB探查器将为您提供有关代码花费最多时间的一些提示。

您还应该在MathWorks手册的Tips For Improving Performance部分阅读许多其他内容。

答案 6 :(得分:1)

mcc根本不会加速你的代码 - 它不是真正的编译器。

在放弃之前,您需要运行探查器并找出所有时间的去向(工具 - >打开Profiler)。此外,明智地使用“tic”和“toc”可以提供帮助。在知道时间到来之前不要优化代码(不要试图猜测)。

请记住在matlab中:

  • 位级操作非常慢
  • 文件I / O很慢
  • 循环通常很慢,但矢量化很快(如果你不知道矢量语法,那就学习它)
  • 核心操作非常快(例如矩阵乘法,fft)
  • 如果您认为可以在C / Fortran / etc中做得更快,可以编写MEX文件
  • 有商业解决方案将matlab转换为C(google“matlab to c”)并且可以正常工作

答案 7 :(得分:1)

您可以将代码移植到“Embedded Matlab”,然后使用Realtime-Workshop将其转换为C.

嵌入式Matlab是Matlab的一个子集。它不支持单元阵列,图形,动态大小的Marice或某些Matrix寻址模式。移植到嵌入式Matlab可能需要相当大的努力。

Realtime-Workshop是代码生成产品的核心。它吐出通用C,或者可以针对一系列嵌入式平台进行优化。对您而言最令人感兴趣的可能是xPC-Target,它将通用硬件视为嵌入式目标。

答案 8 :(得分:1)

我会投票分析+然后看看有哪些瓶颈。

如果瓶颈是矩阵数学,你可能不会做得更好......除了一个大问题是阵列分配。例如如果你有一个循环:

s = [];
for i = 1:50000
  s(i) = 3;
end

这必须继续调整阵列的大小;预设阵列要快得多(以零或NaN开头)&从那里填写:

s = zeros(50000,1);
for i = 1:50000
  s(i) = 3;
end

如果瓶颈重复执行很多函数调用,那就很难了。

如果瓶颈是MATLAB不能快速完成的事情(某些类型的解析,XML,那些类似的东西),那么我会使用Java,因为MATLAB已经在JVM上运行,并且它很容易与任意JAR文件接口。我查看了与C / C ++的接口,它真的很难看。 Microsoft COM是可以的(仅限Windows),但在学习Java之后,我认为我不会再回过头来了。

答案 9 :(得分:0)

正如其他人所指出的那样,缓慢的Matlab代码往往是矢量化不足的结果。

然而,有时甚至完美的矢量化代码也很慢。然后,您还有几个选项:

  1. 查看是否有可以使用的库/工具箱。这些通常被写成非常优化。
  2. 描述您的代码,找到紧凑的地方并重写那些简单的C.将C代码(例如DLL)连接到Matlab很简单,并在文档中介绍。

答案 10 :(得分:-1)

通过Matlab编译器你可能意味着命令mcc,它通过绕过Matlab解释器来加速代码。什么会显着加快MAtlab代码的速度(50-200倍)是使用mex命令编译的实际C代码。