WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Berechnung in Schleife schneller als Matrizenrechnung

 

Beckster07
Forum-Newbie

Forum-Newbie


Beiträge: 1
Anmeldedatum: 17.09.10
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 17.09.2010, 14:27     Titel: Berechnung in Schleife schneller als Matrizenrechnung
  Antworten mit Zitat      
Hallöchen!

Ich wollte letztens mein Programm optimieren und dachte, dass ich doch eine Schleife durch eine Berechnung mit Matrizen ersetzen könnte um dadurch Rechenzeit einzusparen. Jedoch ist das Gegenteil der Fall! Die Berechnung mit Matrizen braucht doppelt solange wie die Berechnung mit der Schleife!
Wie kommt das und welche Möglichkeiten gibt es doch noch Zeit einzusparen?

Ich denke es liegt daran, dass man in der Schleife immer nur eine Spalte aus der Matrix Q ausliest und bei der Matrizenrechnung gleich i-1 Spalten ausgelesen werden und diese Untermatrix extra in den Speicher geladen wird.

Wenn man die Dimensionen verkleinert (also n und k), dann ist die Matrixberechnung schneller!

z.B. bei meinem Rechner:
n = 1000;
k = 50;
Zeit Matrizenrechnung: Elapsed time is 0.008858 seconds.
Zeit Schleifenrechnung: Elapsed time is 0.019846 seconds.

Code:

function test_Orthogonalisierung
clc;
n = 5000;
k = 50;
A = rand(n,k);

Q = zeros(n,k);

tic
Q(:,1) = A(:,1)/norm(A(:,1));
for i = 2:k
    v = A(:,i);
    v = orthov(v,Q,i);
    Q(:,i) = v/norm(v);
end
toc
% Ausgabe: Elapsed time is 0.102404 seconds.
norm(Q'*Q-eye(k))

tic
Q(:,1) = A(:,1)/norm(A(:,1));
for i = 2:k
    v = A(:,i);
    v = orthov_loop(v,Q,i);
    Q(:,i) = v/norm(v);
end
toc
% Ausgabe: Elapsed time is 0.045078 seconds.
% D.h. die Schleife braucht ca. die Hälfte der Zeit!!!!
norm(Q'*Q-eye(k))


%=========================================================================

function v = orthov(v,Q,i)

h = Q(:,1:i-1)'*v;
v = v - Q(:,1:i-1)*h;

function v = orthov_loop(v,Q,j)

for i = 1:j-1
    h = Q(:,i)'*v;
    v = v - Q(:,i)*h;
end
Private Nachricht senden Benutzer-Profile anzeigen


Linus
Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 69
Anmeldedatum: 30.08.10
Wohnort: Aachen
Version: ---
     Beitrag Verfasst am: 17.09.2010, 16:54     Titel:
  Antworten mit Zitat      
Hab das gerade mal versucht, nachzuvollziehen, bin aber nicht so weit gekommen. Ich kann dir nur 3 Dinge sagen:

1.) So kleine Zeitmessungen (< 2 sec) sind immer sehr ungenau und gefährlich. Am besten andere Parameter für längere Berechnungen zum Vergleich benutzen, oder das, was du timen willst, mehrfach in einer weiteren Schleife ausführen lassen!
Man weiß nie genau, was im Hintergrund noch für I/O und CPU-Sachen im Betriebssystem laufen, ob MATLAB alle Funktionen im Cache hat usw.

2.) Nur die Walltime (also echte Zeit, tic, toc) anzuschauen ist auf Multicore-CPUs auch "gefährlich". Zwar interessiert dich im Endeffekt genau diese Zeit (aka "wie lange dauert es eigentlich"), es hilft aber auch, sich zusätzlich noch die benötigte Rechenzeit anzugucken (merke dir vorher cputime() und hinterher, und vergleiche). Dann sieht man auch, wie parallelisiert der Code war.

3.) Nutz den Profiler. Der ist wunderbar für genau solche Fälle. Einfach, wenn deine Funktion im Editor ist, unter "Tools", "Open Profiler" auswählen. Das zeigt dir worans liegt!
_________________

RWTH - Mindstorms NXT Toolbox - free & open source
Private Nachricht senden Benutzer-Profile anzeigen
 
Linus
Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 69
Anmeldedatum: 30.08.10
Wohnort: Aachen
Version: ---
     Beitrag Verfasst am: 17.09.2010, 18:00     Titel:
  Antworten mit Zitat      
Ich denke übrigens, es könnte sehr gut hieran liegen: http://blogs.mathworks.com/loren/2010/01/27/matlab-behavior-for/

Siehe auch z.B. Comment 4.
_________________

RWTH - Mindstorms NXT Toolbox - free & open source
Private Nachricht senden Benutzer-Profile anzeigen
 
Andreas Goser
Forum-Meister

Forum-Meister


Beiträge: 3.654
Anmeldedatum: 04.12.08
Wohnort: Ismaning
Version: 1.0
     Beitrag Verfasst am: 17.09.2010, 22:18     Titel:
  Antworten mit Zitat      
1. Natürlich kann man durch geschickten Code Performance gewinnen, aber sehr, sehr häufig wird viel mehr gerechnet als für die Lösung einer Aufgabe nötig ist (Messwerte liegen in DOUBLE und 1 ms Takt vor - die muss ich nutzen, selbst wenn das System das ich identfizieren will eine Zeitkonstante von 1 Minute hat Shocked ) - nun gut, hier werden keine Messwerte verrechnet und ich schliesse mich der Aussage zu den kleinen Rechenzeiten an.

2. Ja, Schleifen können schneller sein. Ja, MATLAB kann auch schneller als C-Code sein. Wenn ich die Top 10 "Mythen" über MATLAB zusammentragen wollte gehört bestimmt dazu, dass man Schleifen vermeiden muss.

Andreas
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 17.09.2010, 23:43     Titel: Re: Berechnung in Schleife schneller als Matrizenrechnung
  Antworten mit Zitat      
Hallo Beckster07,

ich habe einiges versucht, aber die Schleifen-Method ist unter modernen Matlab Versionen wirklich schnell. Mit einer kleinen Modifikation kann man weitere 10% Rechenzeit sparen:
Code:
function test_Orthogonalisierung
n = 5000;
k = 50;
A = rand(n,k);

Q = zeros(n,k);

tic
for k = 1:100
  Q(:,1) = A(:,1)/norm(A(:,1));
  for i = 2:k
      v = A(:,i);
      v = orthov(v,Q,i);
      Q(:,i) = v/norm(v);
  end
end
toc

tic
for k = 1:100
  Q(:,1) = A(:,1)/norm(A(:,1));
  for i = 2:k
      v = A(:,i);
      v = orthov_loop(v,Q,i);
      Q(:,i) = v/norm(v);
  end
end
toc

%  10% faster
tic
for k = 1:100
  Q(:,1) = A(:,1)/norm(A(:,1));
  for i = 2:k
      v = A(:,i);
      v = orthov_loop_2(v,Q,i);
      Q(:,i) = v/norm(v);
  end
end
toc

% Some further percent faster with inlined loop:
tic
for k = 1:100
  Q(:,1) = A(:,1)/norm(A(:,1));
  for i = 2:k
      v = A(:,i);
      for j = 1:i-1
          q = Q(:, j);
          v = v - q * (q' * v);
      end
      Q(:,i) = v/norm(v);
  end
end
toc

%=============================================
function v = orthov(v,Q,i)
h = Q(:,1:i-1)'*v;
v = v - Q(:,1:i-1)*h;

function v = orthov_loop(v,Q,j)
for i = 1:j-1
    h = Q(:,i)'*v;
    v = v - Q(:,i)*h;
end

function v = orthov_loop_2(v,Q,j)
for i = 1:j-1
    q = Q(:, i);
    v = v - q * (q' * v);
end


Die Schleife aus der Unterfunktion in die Hauptschleife einzubauen bringt nochmal ein paar Prozente, da der Aufruf einer Unterfunktion immer Zeit kostet.
Unter Matlab 6.5 sieht das auch ganz interessant aus:
orthov: 2.18 sec
orthov_loop: 3.7 sec (daher die Meinung, dass Matrizen schneller sind!)
orthov_loop_2: 0.99 sec (aha! Der JIT-Accelerator schlägt zu!)
inlined orthov_loop_2: 0.94 sec

Hoffentlich bearbeitest Du wirklich große Matrizen damit. Ansonsten hatr Dich das Schreiben im Forum dann doch wieder mehr Zeit gekostet, als das Optimieren wieder einbringt. Das ist das alte Problem:
Programmzeit = Programmierzeit + Debugzeit + Laufzeit
Eine Laufzeit-Optimierung sorgt nicht unbedingt dafür, dass die Ergebnisse früher fertig sind...

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Gast11

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 02.08.2011, 08:08     Titel: Re: Berechnung in Schleife schneller als Matrizenrechnung
  Antworten mit Zitat      
Beckster07 hat Folgendes geschrieben:
Hallöchen!

Ich wollte letztens mein Programm optimieren und dachte, dass ich doch eine Schleife durch eine Berechnung mit Matrizen ersetzen könnte um dadurch Rechenzeit einzusparen. Jedoch ist das Gegenteil der Fall! Die Berechnung mit Matrizen braucht doppelt solange wie die Berechnung mit der Schleife!
Wie kommt das und welche Möglichkeiten gibt es doch noch Zeit einzusparen?

Ich denke es liegt daran, dass man in der Schleife immer nur eine Spalte aus der Matrix Q ausliest und bei der Matrizenrechnung gleich i-1 Spalten ausgelesen werden und diese Untermatrix extra in den Speicher geladen wird.

Wenn man die Dimensionen verkleinert (also n und k), dann ist die Matrixberechnung schneller!

z.B. bei meinem Rechner:
n = 1000;
k = 50;
Zeit Matrizenrechnung: Elapsed time is 0.008858 seconds.
Zeit Schleifenrechnung: Elapsed time is 0.019846 seconds.


Hallo,

wenn mich meine Glasaugen nicht trügen, dann hast du folgendes

Elapsed time Matrizenr. < Elapsed time Schleifenr. oder sind
0.008x sec > 0.019x sec ???

Beste Grüße
Gast11
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 02.08.2011, 18:26     Titel: Re: Berechnung in Schleife schneller als Matrizenrechnung
  Antworten mit Zitat      
Hallo Beckster07,

NORM ist langsam. DNorm2 ist schneller und es berechnet die Norm über Spalten- oder Zeilen-Vektoren einer Matrix: http://www.mathworks.com/matlabcentral/fileexchange/29035-dnorm2
Für einzelne Spalten-Vektoren ist dies am schnellsten:
Code:
Q(:,i) = v / sqrt(v' * v);


Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.