3

I have some MATLAB code I've been working with. There are three sections, say A, B, and C. A and C can change, B stays the same regardless.

What I did was separate A, B, and C into separate .m files (not functions, just scripts). A just creates a set of variables, B contains the logic, and C contains plotting for the results. I'll call D a file where all I've done is linearly copy/paste the entire contents of A, B, and C right after each other.

If I run A, then B, then C, the iteration within B goes VERY SLOWLY, about 15 seconds per iteration. If I run D (just A then B then C pasted in) it goes FAST, about 2 seconds per iteration.

Given that MATLAB is running the exact same code in the exact same order, why would the two have such drastically different execution times?

jstm88
  • 3,335
  • 4
  • 38
  • 55
  • 4
    Maybe the MATLAB JIT is able to optimize your code better in D since it can see all of it at once. – Praetorian Jul 21 '11 at 23:08
  • What happens if you make B into a function instead of a script? – k107 Jul 21 '11 at 23:14
  • 2
    also how are you recording execution times? Try `clear all;tic,A;B;C;toc` then compare against `clear all;tic,D;toc`. Anyways, @Praetorian gave a plausible explanation.. – Amro Jul 22 '11 at 00:06
  • Also, let me guess: your use of built-in functions isn't predominant in this code and you have most of your time spent in the interpreter with things like `for` loops etc. This would make it a prime candidate for differences with Matlab JIT. – Chris A. Oct 18 '11 at 12:13

2 Answers2

2

I believe that you have memory issues. Matlab functions actually get their input variables as pointers, but if you change the data, it becomes a copy. So if A,B,C have large input and output, and each one of them modifies a small part of some data, you get a lot of memory allocations.

For example:

function Main()
 x = imread('peppers.png');
 for i=1:size(x,1)
     for j=1:size(x,2)
          x = ChangePixel(x,i,j);
     end
 end
 imshow(x);
end

function A = ChangePixel(A,i,j)
    A(i,j,:) = A(i,j,[3 2 1]);
end

This code will be very slow, since ChangePixel allocates each time a new matrix.

Sometimes, Matlab can detect these kind of operations and use inner optimization. However, one cannot know whether it will take place or not, so it is best to avoid this kind of operations.

Andrey Rubshtein
  • 20,795
  • 11
  • 69
  • 104
  • not exactly the case for you example; MATLAB can detect in-place operations in some cases, and optimize them to avoid making unnecessary copies. See my answer here: http://stackoverflow.com/questions/7228613/in-place-quicksort-in-matlab/7233424#7233424 – Amro Oct 17 '11 at 14:41
  • Thanks Amro. Have you got any example that will always be optimized? – Andrey Rubshtein Oct 17 '11 at 15:26
  • you should read Loren blog post linked in my answer: http://blogs.mathworks.com/loren/2007/03/22/in-place-operations-on-data/ – Amro Oct 17 '11 at 16:02
  • I've read the blog. It looks like no one, even Loren herself can tell whether the JIT optimization will take place or not. That is highly disturbing. – Andrey Rubshtein Oct 18 '11 at 11:51
1

Without a reproducible example, it's hard to say what is happening. I can tell you how to look for yourself though.

Close and reopen MATLAB, so everything is fresh. (Or at least do close all hidden; clear classes; clc;.) Do you get the same timing if you call D before you call A, B, C? If you didn't clear your variables in between, then MATLAB will have had to do less allocation the second time.

If the timings were the same, then you'll need to use the profiler. (Click Desktop -> Profiler.) Profile each script, and make a note of which lines were slow. Do they match up? Can you see any patterns? Are you sure that the same code really is being executed on both cases?

If there's still no obvious reason why the timings are different, then perhaps Praetorian is right, and it's deep JIT magic.

Richie Cotton
  • 118,240
  • 47
  • 247
  • 360
  • ... as for profiling, if it is really 2 vs 15 seconds then the "Ctrl-C" method of profiling explained here might be a good idea: http://stackoverflow.com/questions/375913/what-can-i-use-to-profile-c-code-in-linux/378024#378024 ... basically you `dbstop if error` before calling your code and then interrupt with Ctrl-C when you think it is being slow... doing that a few times gives you a good idea where all the time is being spent. – Jonas Heidelberg Jul 22 '11 at 13:51