Oto matlab's doc czas w ogóle, a jak upływający czas był i jest obecnie mierzone w Matlab. możemy przeczytać, że „tic i toc [oferty] najwyższa dokładność i najbardziej przewidywalne zachowanie”. Myślę, że to jest poprawne stwierdzenie.
Obserwowany spadek wydajności nie jest wynikiem złej miary upływu czasu i nie jest powiązany z funkcjami imshow
lub drawnow
. Będę argumentował, że jest on powiązany z systemem pamięci podręcznej.
Poniższy rysunek przedstawia wyniki czterech testów, z których każdy ma własną miarę bazową tic/toc
(wykreśloną na niebiesko) dla 100 iteracji. Zielona linia pokazuje wyniki w różnych warunkach:
(1) for ii=1:100
t = tic; %single tic/toc
fps(ii,2) = 1./toc(t);
rand(1000); %extra function outside tic/toc
end
Jak donosi w swoim pytaniu, możemy obserwować wolniejsze klatek na sekundę (fps; powiedziałbym 30%), mimo rand
będącego zewnątrz tic bloku/toc . Dodatkowa funkcja może być dowolnego typu (plot
, surf
, imshow
, sum
), zawsze będziesz obserwować spadek wydajności.
(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
W drugim podpólcie blok Tic/Toc powtarza się dwukrotnie. Pomiar fps
jest zatem wykonywany dwa razy i zachowywany jest tylko drugi pomiar. Widzimy, że spadku wydajności już nie ma - tak jak pierwsze wezwanie Tic/Toc przygotowało drugie (rozgrzewka). Interpretuję to w kontekście pamięci podręcznej: instrukcje i/lub dane są wykonywane, a następnie przechowywane w pamięci niskiego poziomu - drugie połączenie jest szybsze.
(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
Trzecie podplot wykorzystało 10.000 tic/toc jako dodatkową funkcję w scenariuszu pojedynczego połączenia. Możesz zobaczyć, że wydajność jest prawie identyczna.Cały zestaw danych/instrukcji w tym podpunkcie jest związany tylko z tic/toc - ponownie, z szybkim dostępem do pamięci podręcznej.
(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
Wreszcie, czwarty wątek pokazuje dwa kolejne bloki połączeń tic/toc. Widzimy, że drugi działa lepiej niż pierwszy (efekt rozgrzewki).
Ogólny wzór pokazany tutaj nie jest związane z imshow
, nie zależy od JIT
z accel
, ale zależy tylko od kolejnych połączeń do danej funkcji. Interpretuję to pod kątem pamięci podręcznej, ale brakuje mi formalnego dowodu.
Oto Działki
i kod
%% 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]);
Jaka wersja MATLAB używasz? Czy te wyniki są spójne? Jeśli tak, spróbuj wyłączyć akcelerację JIT za pomocą funkcji "accel off" przed uruchomieniem tego i sprawdź, czy jest odtwarzalna. –
Spróbuj także użyć FRAPS do pomiarów szybkości klatek. – Mikhail