mit diesem zu einem gewissen automatischen Optimierung Matlab zurückzuführen kann verwendet für seine Basic Linear Algebra Unterprogramm.
Genau wie Sie, dauert meine Konfiguration (OSX 10.8.4, R2012a mit Standardeinstellungen) länger, um idx1 = x~=0
für x (10e5 Elemente) als x (11e5 Elemente) zu berechnen. Siehe das linke Feld der Figur, wo die Verarbeitungszeit (y-Achse) für verschiedene Vektorgrößen (x-Achse) gemessen wird. Sie sehen eine kürzere Verarbeitungszeit für N> 103000. In diesem Fenster habe ich auch die Anzahl der Kerne angezeigt, die während der Berechnung aktiv waren. Sie werden sehen, dass für die Ein-Kern-Konfiguration kein Abfall vorliegt. Dies bedeutet, dass Matlab die Ausführung von ~=
nicht optimiert, wenn 1 Kern aktiv ist (keine Parallelisierung möglich). Matlab ermöglicht einige Optimierungsroutinen, wenn zwei Bedingungen erfüllt sind: mehrere Kerne und ein Vektor ausreichender Größe.
Im rechten Bereich werden die Ergebnisse angezeigt, wenn feature('accel','on'/off')
auf Aus gestellt ist (doc). Hier ist nur ein Kern aktiv (1-Kern und 4-Kern sind identisch) und daher ist keine Optimierung möglich.
Die Funktion zum Aktivieren/Deaktivieren der Kerne ist schließlich maxNumCompThreads
. Gemäß Loren Shure steuert maxNumCompThreads sowohl das JIT als auch BLAS. Da bei der Performance keine Rolle spielte, ist BLAS die letzte verbleibende Option.
Ich überlasse den letzten Satz an Loren: "Die wichtigste Nachricht hier ist, dass Sie diese Funktion [maxNumCompThreads] überhaupt nicht verwenden sollten! Warum? Weil wir möchten, dass MATLAB den besten Job macht möglich für dich. "
accel = {'on';'off'};
figure('Color','w');
N = 100000:1000:105000;
for ind_accel = 2:-1:1
eval(['feature(''accel'',''' accel{ind_accel} ''')']);
tElapsed = zeros(4,length(N));
for ind_core = 1:4
maxNumCompThreads(ind_core);
n_core = maxNumCompThreads;
for ii = 1:length(N)
fprintf('core asked: %d(true:%d) - N:%d\n',ind_core,n_core, ii);
x = round(rand(N(ii),1)*5)-2;
idx1 = x~=0;
tStart = tic;
for t = 1:5000
idx1 = x~=0;
end
tElapsed(ind_core,ii) = toc(tStart);
end
end
h2 = subplot(1,2,ind_accel);
plot(N, tElapsed,'-o','MarkerSize',10);
legend({('1':'4')'});
xlabel('Vector size','FontSize',14);
ylabel('Processing time','FontSize',14);
set(gca,'FontSize',14,'YLim',[0.2 0.7]);
title(['accel ' accel{ind_accel}]);
end
Nun, ich würde auf jeden Fall davon ausgehen, 'abs (x)> 0 'würde langsamer sein, weil es wirklich zwei Operationen tut, aber die N-Studie von 100000, bedeutet dies nicht folgen. Seltsam. Ich würde jedoch fast immer 'x ~ = 0' verwenden, weil es nur eine Operation ausführt. Beachten Sie auch, der Unterschied zwischen den beiden war nicht so hoch für mich wie für Sie. Der dritte Versuch wurde nur um 0,4 Sekunden getrennt, nicht 1.5 – MZimmerman6
mein einziger Gedanke wäre, es wäre eine seltsame Speicherzuweisung im Hintergrund, die der 100k Versuch wirft – MZimmerman6
Ich sehe die gleiche Sache, aber nicht so drastisch (R2012b, OS X 10.8.4). Ich würde nicht annehmen, dass "abs (x)> 0" zwei Operationen ausführt. Sobald JIT kompiliert wurde, kann das Vorzeichenbit in dem Vergleich ignoriert werden. Es ist eigentlich der 'x ~ = 0'-Fall, der komplizierter ist (äquivalent zu 'x> 0 | x <0'). Ein möglicher Grund für den Unterschied zwischen den Größen könnte [Cache fehlt] sein (https://en.wikipedia.org/wiki/CPU_cache#Cache_miss), das im Detail [hier] (http://stackoverflow.com/questions) diskutiert wird/8547778/warum-ist-eine-Schleife-so-viel-langsamer-als-zwei-Schleifen). – horchler