为什么我在使用 MATLAB 编译器时没有看到显着的加速?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/137011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why don't I see a significant speed-up when using the MATLAB compiler?
提问by Dan Lenski
I have a lot of nice MATLAB code that runs too slowly and would be a pain to write over in C. The MATLAB compiler for C does not seem to help much, if at all. Should it be speeding execution up more? Am I screwed?
我有很多很好的 MATLAB 代码,它们运行速度太慢,用 C 编写会很痛苦。 C 的 MATLAB 编译器似乎没有多大帮助,如果有的话。它应该加快执行速度吗?我搞砸了吗?
回答by WalkingRandomly
If you are using the MATLAB complier(on a recent version of MATLAB) then you will almost certainly not see any speedups at all. This is because all the compiler actually does is give you a way of packaging up your code so that it can be distributed to people who don't have MATLAB. It doesn't convert it to anything faster (such as machine code or C) - it merely wraps it in C so you can call it.
如果您使用的是MATLAB 编译器(在最新版本的 MATLAB 上),那么您几乎肯定不会看到任何加速。这是因为编译器实际上所做的就是为您提供一种打包代码的方法,以便将其分发给没有 MATLAB 的人。它不会将其转换为更快的任何内容(例如机器代码或 C)——它只是将它包装在 C 中,以便您可以调用它。
It does this by getting your code to run on the MATLAB Compiler Runtime (MCR) which is essentially the MATLAB computational kernel - your code is still being interpreted. Thanks to the penalty incurred by having to invoke the MCR you may find that compiled code runs more slowly than if you simply ran it on MATLAB.
它通过让您的代码在本质上是 MATLAB 计算内核的 MATLAB 编译器运行时 (MCR) 上运行来实现这一点——您的代码仍在被解释。由于必须调用 MCR 所带来的惩罚,您可能会发现编译后的代码运行速度比在 MATLAB 上运行时慢。
Put another way - you might say that the compiler doesn't actually compile - in the traditional sense of the word at least.
换句话说——你可能会说编译器实际上并没有编译——至少在这个词的传统意义上是这样的。
Older versions of the compiler worked differently and speedups could occur in certain situations. For Mathwork's take on this go to
旧版本的编译器工作方式不同,在某些情况下可能会出现加速。对于 Mathwork 对此的看法,请访问
http://www.mathworks.com/support/solutions/data/1-1ARNS.html
http://www.mathworks.com/support/solutions/data/1-1ARNS.html
回答by dwj
In my experience slow MATLAB code usually comes from not vectorizing your code (i.e., writing for-loops instead of just multiplying arrays (simple example)).
根据我的经验,缓慢的 MATLAB 代码通常来自未对代码进行矢量化(即,编写 for 循环而不是仅将数组相乘(简单示例))。
If you are doing file I/O look out for reading data in one piece at a time. Look in the help files for the vectorized version of fscanf.
如果您正在执行文件 I/O,请注意一次读取一份数据。查看 fscanf 的矢量化版本的帮助文件。
Don't forget that MATLAB includes a profiler, too!
不要忘记 MATLAB 也包含一个分析器!
回答by Dan Lenski
I'll echo what dwj said: if your MATLAB code is slow, this is probably because it is not sufficiently vectorized. If you're doing explicit loops when you could be doing operations on whole arrays, that's the culprit.
我会回应 dwj 所说的:如果您的 MATLAB 代码很慢,这可能是因为它没有充分矢量化。如果您在可以对整个数组执行操作时执行显式循环,这就是罪魁祸首。
This applies equally to all array-oriented dynamic languages: Perl Data Language, Numeric Python, MATLAB/Octave, etc. It's even true to some extent in compiled C and FORTRAN compiled code: specially-designed vectorization libraries generally use carefully hand-coded inner loops and SIMD instructions (e.g. MMX, SSE, AltiVec).
这同样适用于所有面向数组的动态语言:Perl Data Language、Numeric Python、MATLAB/Octave 等。在编译的 C 和 FORTRAN 编译代码中甚至在某种程度上也是如此:专门设计的矢量化库通常使用精心手工编码的内部循环和 SIMD 指令(例如 MMX、SSE、AltiVec)。
回答by Mr Fooz
First, I second all the above comments about profiling and vectorizing.
首先,我将上述所有关于分析和矢量化的评论放在第二位。
For a historical perspective...
从历史的角度...
Older version of Matlab allowed the user to convert m files to mex functions by pre-parsing the m code and converting it to a set of matlab library calls. These calls have all the error checking that the interpreter did, but old versions of the interpreter and/or online parser were slow, so compiling the m file would sometimes help. Usually it helped when you had loops because Matlab was smart enough to inline some of that in C. If you have one of those versions of Matlab, you can try telling the mex script to save the .c file and you can see exactly what it's doing.
旧版本的 Matlab 允许用户通过预解析 m 代码并将其转换为一组 matlab 库调用来将 m 文件转换为 mex 函数。这些调用具有解释器所做的所有错误检查,但旧版本的解释器和/或在线解析器很慢,因此编译 m 文件有时会有所帮助。通常当你有循环时它会有所帮助,因为 Matlab 足够聪明,可以在 C 中内联其中的一些。如果你有那些版本的 Matlab,你可以尝试告诉 mex 脚本保存 .c 文件,你可以看到它到底是什么正在做。
In more recent version (probably 2006a and later, but I don't remember), Mathworks started using a just-in-time compiler for the interpreter. In effect, this JIT compiler automatically compiles all mex functions, so explicitly doing it offline doesn't help at all. In each version since then, they've also put a lot of effort into making the interpreter much faster. I believe that newer versions of Matlab don't even let you automatically compile m files to mex files because it doesn't make sense any more.
在较新的版本中(可能是 2006a 及更高版本,但我不记得了),Mathworks 开始为解释器使用即时编译器。实际上,这个 JIT 编译器会自动编译所有 mex 函数,因此明确地离线执行它根本没有帮助。从那时起,在每个版本中,他们也付出了很多努力使解释器更快。我相信较新版本的 Matlab 甚至不允许您自动将 m 文件编译为 mex 文件,因为它不再有意义。
回答by Todd
The MATLAB compiler wraps up your m-code and dispatches it to a MATLAB runtime. So, the performance you see in MATLAB should be the performance you see with the compiler.
MATLAB 编译器包装您的 m 代码并将其分派到 MATLAB 运行时。因此,您在 MATLAB 中看到的性能应该是您在编译器中看到的性能。
Per the other answers, vectorizing your code is helpful. But, the MATLAB JIT is pretty good these days and lots of things perform roughly as well vectorized or not. That'a not to say there aren't performance benefits to be gained from vectorization, it's just not the magic bullet it once was. The only way to really tell is to use the profiler to find out where your code is seeing bottlenecks. Often times there are some places where you can do local refactoring to really improve the performance of your code.
根据其他答案,对代码进行矢量化很有帮助。但是,现在 MATLAB JIT 非常好,很多东西的性能都大致与矢量化一样好。这并不是说矢量化不会获得性能优势,它只是不再是曾经的灵丹妙药。真正判断的唯一方法是使用分析器找出您的代码在哪里遇到瓶颈。很多时候,您可以在某些地方进行本地重构以真正提高代码的性能。
There are a couple of other hardware approaches you can take on performance. First, much of the linear algebra subsystem is multithreaded. You may want to make sure you have enabled that in your preferences if you are working on a multi-core or multi-processor platform. Second, you may be able to use the parallel computing toolbox to take more advantage of multiple processors. Finally, if you are a Simulink user, you may be able to use emlmex to compile m-code into c. This is particularly effective for fixed point work.
您可以采用其他几种硬件方法来提高性能。首先,大部分线性代数子系统都是多线程的。如果您在多核或多处理器平台上工作,您可能需要确保在您的首选项中启用了它。其次,您或许可以使用并行计算工具箱来更多地利用多处理器。最后,如果您是 Simulink 用户,您或许可以使用 emlmex 将 m 代码编译成 c。这对于定点工作特别有效。
回答by user27315
Have you tried profiling your code? You don't need to vectorize ALL your code, just the functions that dominate running time. The MATLAB profiler will give you some hints on where your code is spending the most time.
您是否尝试过分析您的代码?您不需要矢量化所有代码,只需矢量化控制运行时间的函数。MATLAB 探查器将为您提供一些有关代码花费最多时间的提示。
There are many other things you you should read up on the Tips For Improving Performancesection in the MathWorks manual.
回答by edgar.holleis
You could port your code to "Embedded Matlab" and then use the Realtime-Workshop to translate it to C.
您可以将代码移植到“嵌入式 Matlab”,然后使用 Realtime-Workshop 将其转换为 C。
Embedded Matlab is a subset of Matlab. It does not support Cell-Arrays, Graphics, Marices of dynamic size, or some Matrix addressing modes. It may take considerable effort to port to Embedded Matlab.
嵌入式 Matlab 是 Matlab 的一个子集。它不支持单元阵列、图形、动态大小的 Marice 或某些矩阵寻址模式。移植到嵌入式 Matlab 可能需要相当多的努力。
Realtime-Workshop is at the core of the Code Generation Products. It spits out generic C, or can optimize for a range of embedded Platforms. Most interresting to you is perhaps the xPC-Target, which treats general purpose hardware as embedded target.
Realtime-Workshop 是代码生成产品的核心。它会输出通用 C,或者可以针对一系列嵌入式平台进行优化。对您来说最有趣的可能是 xPC-Target,它将通用硬件视为嵌入式目标。
回答by edgar.holleis
mcc won't speed up your code at all--it's not really a compiler.
mcc 根本不会加速您的代码——它不是真正的编译器。
Before you give up, you need to run the profiler and figure out where all your time is going (Tools->Open Profiler). Also, judicious use of "tic" and "toc" can help. Don't optimize your code until you know where the time is going (don't try to guess).
在你放弃之前,你需要运行探查器并弄清楚你所有的时间都去哪儿了(工具->打开探查器)。此外,明智地使用“tic”和“toc”会有所帮助。在您知道时间去哪里之前不要优化您的代码(不要试图猜测)。
Keep in mind that in matlab:
请记住,在 matlab 中:
- bit-level operations are really slow
- file I/O is slow
- loops are generally slow, but vectorizing is fast (if you don't know the vector syntax, learn it)
- core operations are really fast (e.g. matrix multiply, fft)
- if you think you can do something faster in C/Fortran/etc, you can write a MEX file
- there are commercial solutions to convert matlab to C (google "matlab to c") and they work
- 位级操作真的很慢
- 文件 I/O 很慢
- 循环通常很慢,但矢量化很快(如果您不知道矢量语法,请学习它)
- 核心操作非常快(例如矩阵乘法,fft)
- 如果你认为你可以在 C/Fortran/etc 中做一些更快的事情,你可以写一个 MEX 文件
- 有将 matlab 转换为 C(谷歌“matlab to c”)的商业解决方案,并且它们可以工作
回答by Jason S
I would vote for profiling + then look at what are the bottlenecks.
我会投票支持分析 + 然后看看瓶颈是什么。
If the bottleneck is matrix math, you're probably not going to do any better... EXCEPT one big gotcha is array allocation. e.g. if you have a loop:
如果瓶颈是矩阵数学,你可能不会做得更好......除了一个大问题是数组分配。例如,如果你有一个循环:
s = [];
for i = 1:50000
s(i) = 3;
end
This has to keep resizing the array; it's much faster to presize the array (start with zeros or NaN) & fill it from there:
这必须不断调整数组的大小;预先调整数组的大小(从零或 NaN 开始)并从那里填充它要快得多:
s = zeros(50000,1);
for i = 1:50000
s(i) = 3;
end
If the bottleneck is repeated executions of a lot of function calls, that's a tough one.
如果瓶颈是重复执行大量函数调用,那将是一个棘手的问题。
If the bottleneck is stuff that MATLAB doesn't do quickly (certain types of parsing, XML, stuff like that) then I would use Java since MATLAB already runs on a JVM and it interfaces really easily to arbitrary JAR files. I looked at interfacing with C/C++ and it's REALLY ugly. Microsoft COM is ok (on Windows only) but after learning Java I don't think I'll ever go back to that.
如果瓶颈是 MATLAB 不能快速完成的事情(某些类型的解析、XML 之类的东西),那么我会使用 Java,因为 MATLAB 已经在 JVM 上运行,并且它可以很容易地与任意 JAR 文件接口。我看着与 C/C++ 的接口,它真的很难看。Microsoft COM 还可以(仅在 Windows 上),但在学习了 Java 之后,我认为我再也不会回到过去了。
回答by Eli Bendersky
As others has noted, slow Matlab code is often the result of insufficient vectorization.
正如其他人所指出的,缓慢的 Matlab 代码通常是矢量化不足的结果。
However, sometimes even perfectly vectorized code is slow. Then, you have several more options:
然而,有时甚至完美的矢量化代码也很慢。然后,您还有更多选择:
- See if there are any libraries / toolboxes you can use. These were usually written to be very optimized.
- Profile your code, find the tight spots and rewrite those in plain C. Connecting C code (as DLLs for instance) to Matlab is easy and is covered in the documentation.
- 查看是否有任何可以使用的库/工具箱。这些通常被编写为非常优化。
- 分析您的代码,找到不足之处并用纯 C 重写它们。将 C 代码(例如 DLL)连接到 Matlab 很容易,文档中有介绍。

