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は含めません。imshowtic-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 [offers] は最高の精度と最も予測可能な動作」を読み取ることができます。妥当な発言だと思います。

ここで観察されたパフォーマンスの低下は、経過時間の不適切な測定によるものではなく、imshowまたはdrawnow関数の使用とは関係ありません。それはキャッシュシステムに関連していると主張します。

tic/toc下の図は、4 つのテストの結果を示しています。それぞれのテストには、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 ブロックの外にあるにもかかわらず、1 秒あたりのフレーム数 (FPS; 30% と言うでしょう) が遅いことがわかります。追加機能は任意のタイプ ( plotsurfimshowsum) にすることができ、常にパフォーマンスの低下が見られます。

(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

2 番目のサブプロットでは、tic/toc ブロックが 2 回繰り返されます。したがって、fps測定は 2 回実行され、2 番目の測定のみが保持されます。最初の tic/toc 呼び出しが 2 番目の呼び出し (ウォームアップ) を準備したように、パフォーマンスの低下はもうないことがわかります。これをキャッシュの観点から解釈します。命令および/またはデータが実行され、低レベルのメモリに保持されます。2 番目の呼び出しの方が高速です。

(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

3 番目のサブプロットでは、1 回の呼び出しシナリオで追加関数として 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

最後に、4 番目のサブプロットは、tic/toc 呼び出しの 2 つの連続したブロックを示しています。2 番目の方が 1 番目よりもパフォーマンスが優れていることがわかります (ウォームアップ効果)。

ここに示されている全体的なパターンは、 に関連してimshowおらず、 に依存していませんJITaccel、特定の関数への連続した呼び出しのみに依存しています。私はこれをキャッシュの観点から解釈していますが、ある種の正式な証拠がありません。

ここにプロットがあります

ここに画像の説明を入力

そしてコード

%% 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 に答える