13

我正在循环测量一些代码

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);

我得到平均 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);

而且我的 fps 慢了大约 20%-30%。为什么会这样?因为imshow()在外面tic-toc

4

2 回答 2

4

这是一个关于时间的matlab文档,以及过去和当前在matlab中测量的时间。我们可以读到“ tic 和 toc [提供] 最高精度和最可预测的行为”。我认为这是有效的说法。

这里观察到的性能下降并不是由于对经过时间的错误测量,也与使用imshowdrawnow功能无关。我会争辩说它与缓存系统有关。

下图显示了四个测试的结果,每个测试都有自己的tic/toc基线测量(以蓝色绘制),用于 100 次迭代。绿线显示不同条件下的性能:

(1)    for ii=1:100
         t = tic;                %single tic/toc
         fps(ii,2) = 1./toc(t); 
         rand(1000);             %extra function outside tic/toc
       end

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

在第二个子图中,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

第三个子图在单个呼叫场景中使用 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

最后,第四个子图显示了两个连续的 tic/toc 调用块。我们可以看到第二个比第一个表现更好(热身效果)。

此处显示的整体模式与 无关imshow,不依赖于JITof 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]);
于 2013-09-03T00:03:51.357 回答
3

这可能是由于您的处理器的多线程能力。

MATLAB 使用的计算线程数基于 的值maxNumCompThreads。如果将其设置为1,那么理论上两种情况都应该产生相同的 fps。

你可以做到这一点:

LASTN = maxNumCompThreads(N);

这里N应该是1并且LASTN会给你之前的最大计算线程数,如果你想重置首选项,这可能会很有用。

于 2013-09-02T11:19:20.803 回答