Lar*_*bar 13 performance matlab profiling
我在循环中测量一些代码
fps = zeros(1, 100);
for i=1:100
t = tic
I = fetch_image_from_source(); % function to get image
fps(i) = 1./ toc(t);
end
plot(fps);
Run Code Online (Sandbox Code Playgroud)
而我平均50 fps.
然后我想添加imshow()到我的代码中.我明白这imshow很慢,但我不会包含imshow内部tic-toc命令:
fps = zeros(1, 100);
figure;
for i=1:100
t = tic
I = fetch_image_from_source(); % function to get image
fps(i) = 1./ toc(t);
imshow(I); drawnow;
end
plot(fps);
Run Code Online (Sandbox Code Playgroud)
而且我的fps速度提高了约20%-30%.为什么会这样?因为imshow()在外面tic-toc
这是一个关于一般时间的matlab 文档,以及 matlab 中过去和现在如何测量经过的时间。我们可以读到“ tic 和 toc [提供]最高的准确性和最可预测的行为”。我认为这是有效的陈述。
imshow这里观察到的性能下降并不是由于对运行时间的测量不当造成的,也与或函数的使用无关drawnow。我认为它与缓存系统有关。
下图显示了四次测试的结果,每个测试都有自己的tic/toc100 次迭代的基线测量(以蓝色绘制)。绿线显示了不同条件下的性能:
(1) for ii=1:100
t = tic; %single tic/toc
fps(ii,2) = 1./toc(t);
rand(1000); %extra function outside tic/toc
end
Run Code Online (Sandbox Code Playgroud)
rand正如您的问题中所报告的,尽管在 tic/toc 块之外,我们还是可以观察到每秒帧数较慢(FPS;我想说 30%) 。额外的函数可以是任何类型(plot, surf, imshow, sum),您将始终观察到性能下降。
(2) for ii=1:100
t = tic; %first tic/toc
fps(ii,2) = 1./toc(t);
t = tic; %second tic/toc
fps(ii,2) = 1./toc(t);
rand(1000); %extra function outside tic/toc
end
Run Code Online (Sandbox Code Playgroud)
在第二个子图中,tic/toc 块重复两次。因此,测量fps执行两次并且仅保留第二次测量。我们看到性能下降不再存在 - 就像第一个 tic/toc 调用准备第二个(热身)一样。我从缓存的角度解释这一点:指令和/或数据被执行,然后保存在低级内存中 - 第二次调用速度更快。
(3) for ii=1:100
t = tic; %first tic/toc
fps(ii,2) = 1./toc(t);
for ij = 1:10000 %10,000 extra tic/toc
tic;
tmp = toc;
end
end
Run Code Online (Sandbox Code Playgroud)
第三个子图在单次调用场景中使用 10,000 tic/toc 作为额外函数。您可以看到性能几乎相同。该子图中的整套数据/指令仅与 tic/toc 相关 - 再次,具有快速缓存访问。
(4) for ii=1:100 %first tic/toc block
t = tic;
fps(ii,1) = 1./toc(t);
end
for ii=1:100 %second tic/toc block
t = tic;
fps(ii,2) = 1./toc(t);
end
Run Code Online (Sandbox Code Playgroud)
最后,第四个子图显示了两个连续的 tic/toc 调用块。我们可以看到第二个比第一个表现更好(热身效果)。
这里显示的整体模式与 无关imshow,也不依赖于JIT,accel而仅依赖于对特定函数的连续调用。我从缓存的角度解释了这一点,但我缺乏某种正式的证据。
这是情节
和代码
%% EXTRA FUNCTION (single call)
fps = zeros(2, 100);
% first case: 100 tic/toc
for ii=1:100
t = tic;
fps(ii,1) = 1./toc(t);
end
%second case: 100 tic/toc + additional function
for ii=1:100
t = tic;
fps(ii,2) = 1./toc(t);
% graph or scalar functions (uncomment to test)
%drawnow;
%plot(1:10)
rand(1000);
%ones(1000, 1000);
%sum(1:1000000);
%diff(1:1000000);
end
h = figure('Color','w','Position',[10 10 600 800]);
subplot(4,1,1);
plot(fps); legend({'tic/toc only','extra function'});
ylabel('FPS');
title('extra function, single call','FontSize',14);
set(gca,'FontSize',14, 'YLim', [0 3.5e5]);
%% EXTRA FUNCTION (double call)
fps = zeros(2, 100);
% first case: 100 tic/toc
for ii=1:100
t = tic;
fps(ii,1) = 1./toc(t);
end
%second case: 100 tic/toc + additional function (except tic/toc)
for ii=1:100
%first call
t = tic;
fps(ii,2) = 1./toc(t);
%second call (identical to first)
t = tic;
fps(ii,2) = 1./toc(t);
rand(1000);
end
subplot(4,1,2);
plot(fps); legend({'tic/toc only','extra function'});
ylabel('FPS');
title('extra function, double call','FontSize',14);
set(gca,'FontSize',14, 'YLim', [0 3.5e5]);
%% EXTRA FUNCTION (double call)
fps = zeros(2, 100);
% first case: 100 tic/toc
for ii=1:100
t = tic;
fps(ii,1) = 1./toc(t);
end
%second case: 100 tic/toc + 10000 tic/toc
for ii=1:100
t = tic;
fps(ii,2) = 1./toc(t);
for ij = 1:10000
tic;
tmp = toc;
end
end
subplot(4,1,3);
plot(fps); legend({'tic/toc','extra tic/toc'});
ylabel('FPS');
title('Identical function calls','FontSize',14);
set(gca,'FontSize',14, 'YLim', [0 3.5e5]);
%% TIC/TOC call twice
fps = zeros(2, 100);
% first case: 100 tic/toc
for ii=1:100
t = tic;
fps(ii,1) = 1./toc(t);
end
for ii=1:100
t = tic;
fps(ii,2) = 1./toc(t);
end
subplot(4,1,4);
plot(fps); legend({'tic/toc (1)','tic/toc (2)'});
ylabel('FPS');
title('tic/toc twice','FontSize',14);
set(gca,'FontSize',14, 'YLim', [0 3.5e5]);
Run Code Online (Sandbox Code Playgroud)