MATLAB Answers

Michael
1

Linkaxes much slower in 2015a

Asked by Michael
on 23 Apr 2015
Latest activity Commented on by Sean de Wolski
on 24 Apr 2015
I'm upgrading from 2013a to the 2015a and I'm finding the handling of graphics on multiple axes is much slower.
For example, take the following simple code:
figure;
ax(1)=subplot(211);
imagesc(peaks(1000));
ax(2)=subplot(212);
imagesc(peaks(1000));
linkaxes(ax,'x');
tic;
for i=1:1000
xlim(xlim*.999);
drawnow;
end
toc
This takes ~10 seconds to run on 2013a and ~30 seconds to run on 2015a, even when turning of graphics smoothing and switching to painters.
I've run profiler and it says most of the time is being taken up LinkProp.processPostUpdate().
Any suggestions of what to do (other than not using linkaxes)?

  0 Comments

Sign in to comment.

2 Answers

Answer by Mike Garrity
on 24 Apr 2015
Edited by Mike Garrity
on 24 Apr 2015
 Accepted Answer

This is an interesting case. There's a lot of stuff going on here. I'm always looking for good performance cases for our graphics blog. This looks like it'd be a good one.
I can't repro your 30 second number, even with 'opengl software'. I get something more like 17 seconds. I'd be interested in what 'opengl info' says on your machine.
First of all, the linkaxes/subplot combination can often cause performance issues because they're both trying to fiddle with the axes positions. You can see this if you replace the calls to subplot with calls to axes:
ax(1)=axes('Position',[.13 .5838 .775 .3412]);
ax(2)=axes('Position',[.13 .11 .775 .3412]);
On my machine that goes from about 17 seconds to about 12 seconds.
But getting past that is tricky because it's actually limited by the rendering side at that point. This means that we need to look at what's going on over on the graphics card. The first option in this case is not to have MATLAB wait for the graphics card. You can do this with the new limitrate option to drawnow, as I described in this blog post. That'll give you a really big speedup. It's not useful if you really want to wait and see each frame, but in this case we're actually generating frames faster than your computer's monitor and your eye can process them, so it might be helpful.
But it's also worth looking into why the graphics card is limiting us here. We're getting 1,000 frames in 12 seconds. That's about 83 frames per second. That seems low for two images. I did some digging, and the issue is actually the tick labels. OpenGL doesn't actually have direct support for drawing text. We send the graphics card texture maps with the pictures of the text strings. In this case, we're not realizing that the tick labels aren't changing and we're sending those texture maps across to the card every frame. You'll see a big speed up if you remove the tick labels:
set(ax,'XTickLabel',{},'YTickLabel',{})
But obviously that's not too helpful, is it?
The other way to get around this is the one you already guessed. If we switch the renderer to painters, then we can draw the text directly. That speeds up the text drawing, and if you compare opengl and painters in 14a, you'll see a big difference, but it doesn't really help in 15a. The problem is that the new painters isn't as fast as the old one was at drawing those images. That's because there's a lot of new stuff in there to support features like transparency, which the old version of painters didn't do.
We're working on improving the new opengl renderer's smarts in managing the texturemaps for cases like this, and we're also working on improving the new painters renderer's handling of some of these image cases. Unfortunately you probably won't see big improvements in either of those areas for a while, but I hope that it's at least useful to have some understanding of what's going on under the covers.

  0 Comments

Sign in to comment.


Answer by Michael
on 24 Apr 2015
Edited by Michael
on 24 Apr 2015

Thanks so much. This is very helpful in understanding the issues at hand. I've been seeing major decreases in speed in my code since upgrading, and it seems that I will not be able to get the same performance and functionality until the renderers are optimized.
I have to deal with backwards compatibility with pre-2014b versions. Do you suggest using
verLessThan()
to handle putting in new commands like "drawnow limitrate"?

  1 Comment

Yes, verLessThan is the best way to make decisions based on release.

Sign in to comment.