What is drawnow doing?
이전 댓글 표시
Hello everyone.
I'm working on a code where I need to alternate the display of two complex plots in a very short time. The time for creating each plot is quite high (4-5 seconds) and I want to alternate them with a lag of 0.1 seconds. Creating a new plot every 0.1 seconds is therefore completely useless.
My idea was to create the two plots in two different axes and alternate the visibility of them. The problem is that drawnow keeps taking a very long time just to show one axes instead of the other.
Is there any way I can speed up this process?
Example of code:
figure
x1 = rand(100000,1);
y1 = rand(100000,1);
x2 = rand(100000,1);
y2 = rand(100000,1);
t = tic;
delay = 0.5;
flag = 0;
while 1
if toc(t) > delay
if flag
plot(x1,y1,'.')
flag = 0;
else
plot(x2,y2,'.')
flag = 1;
end
drawnow
end
end
답변 (1개)
Walter Roberson
2015년 11월 13일
편집: Walter Roberson
2015년 11월 14일
figure
x1 = rand(100000,1);
y1 = rand(100000,1);
x2 = rand(100000,1);
y2 = rand(100000,1);
p1 = plot(x1,y1,'.', 'visible', 'off');
p2 = plot(x2,y2,'.', 'visible', 'off');
t = tic;
delay = 0.5;
flag = 0;
while 1
if toc(t) > delay
if flag
set(p2, 'visible', 'off');
set(p1, 'visible', 'on');
flag = 0;
else
set(p1, 'visible', 'off');
set(p2, 'visible', 'on');
flag = 1;
end
drawnow
end
end
댓글 수: 9
Second set should be set(p1, ... not p2. And there should be a
hold on
Alessandro Masullo
2015년 11월 13일
Mike Garrity
2015년 11월 13일
You're on the right track here. The basic idea is that we want to park the two plots on the graphics card, and then just tell the card which one to draw each frame. The code you've got almost does that.
Here's a version I tweaked a tiny bit:
figure
hold on
drawnow
rng default
x1 = rand(100000,2);
y1 = rand(100000,2);
x2 = rand(100000,2);
y2 = rand(100000,2);
p1 = plot(x1,y1,'.', 'visible', 'off');
p2 = plot(x2,y2,'.', 'visible', 'off');
nframes = 500;
ft = zeros(1,nframes);
t = tic;
delay = 0.1;
flag = 0;
for i=1:nframes
t2 = tic;
if flag
set(p1,'Visible','off');
set(p2,'Visible','on');
flag = 0;
else
set(p1,'Visible','on');
set(p2,'Visible','off');
flag = 1;
end
drawnow
ft(i) = toc(t2);
end
sprintf('%g FPS', 1/median(ft))
When I run this on my machine (an nVidia K600) I get 38 frames per second.
But we can do better. The problem with this is that we're changing a property on the line object. When we do this, MATLAB decides something's changed and it resends the data to the card. We don't want to do that.
But how do we change the visibility without modifying the object? The trick is to put the line object in a group and toggle the visibility on that. That would look something like this:
figure
drawnow
rng default
x1 = rand(100000,2);
y1 = rand(100000,2);
x2 = rand(100000,2);
y2 = rand(100000,2);
g1 = hggroup;
p1 = plot(x1,y1,'.','Parent',g1);
g2 = hggroup;
p2 = plot(x2,y2,'.','Parent',g2);
nframes = 500;
ft = zeros(1,nframes);
t = tic;
delay = 0.1;
flag = 0;
for i=1:nframes
t2 = tic;
if flag
g1.Visible = 'off';
g2.Visible = 'on';
flag = 0;
else
g1.Visible = 'on';
g2.Visible = 'off';
flag = 1;
end
drawnow
ft(i) = toc(t2);
end
sprintf('%g FPS', 1/median(ft))
When I run this version, I get 90 frames per second.
Does that help?
Alessandro Masullo
2015년 11월 16일
Mike Garrity
2015년 11월 16일
It's not that drawnow is slower. What changed is that more work is being done on the graphics card. Since drawnow is where we synch up all the different threads, it is more likely to show up as a hotspot in the profiler. This usually means that the different threads are out of balance and are spending a lot of time waiting for each other.
Are you saying that when you run the code in my previous comment above, you get 8 FPS? That's very surprising, because your machine is actually very similar to the one I'm using right now. I just ran it on this machine with R2015a, and it prints out '98.9303 FPS'. If you are getting wildly different results with a similar system, could you please run the following command and add the output in a comment here?
opengl info
Thanks.
Alessandro Masullo
2015년 11월 17일
Alessandro Masullo
2015년 11월 17일
Mike Garrity
2015년 11월 17일
It's really not an answer yet. We need to figure out why you are getting softwareopengl. There are a couple of reasons this might happen. Two common reasons.
- We have a blacklist for some drivers we've seen a lot of problems with.
- The system that reports crashes back to us looks at the call stack. If the crash was in your graphics card driver, we'll set your default to softwareopengl to prevent it happening again.
Could you start MATLAB with the -hardwareopengl switch and then do opengl info again? That's probably the easiest way to get all of the details about your graphics card. I'll see if I can find someone who can help figure out what's going on. Hopefully it'll be as simple as updating your driver to a different version.
Alessandro Masullo
2015년 11월 18일
카테고리
도움말 센터 및 File Exchange에서 Graphics Performance에 대해 자세히 알아보기
제품
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!