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

for-Schleife - Zeit der Durchläufe nimmt plötzlich zu

 

gast

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 07.09.2010, 19:12     Titel: for-Schleife - Zeit der Durchläufe nimmt plötzlich zu
  Antworten mit Zitat      
Habe folgenden Code erstellt (F ist Eingabeparameter; v,b,L sind fest vorgegeben):
Code:

x = 0;
for r = 1:F
    for d = 2:400
        for h = 1:20
            x = x + 1;
            z(v + x) = 10 + x;
            s(v+x*5-4:v+x*5) = [20+x 50+x 55+x];
            wz = ones(1,4) * (-1);
            w(v + x*5-4:v + x*5) = wz;
            b(x) = - L(d,h);
            display(x);
        end
    end
end
 



Das x lasse ich ausgeben, um zu sehen, wie schnell die Schleife durchläuft. Bei F = 80 ist nach einigen Sekunden x = 130.000 und die Durchläufe werden deutlich langsamer. Bei F = 10 beginnt es bereits x=15000 langsam zu werden.

Alle Vektoren, die innerhalb der Schleife verändert werden, sind vordefiniert (damit sich die Größe nicht mit jedem Schleifendurchlauf ändert).

Müssten die Operationen nicht mit konstanter Geschwindigkeit durchlaufen, sodass die komplette Schleife relativ schnell beendet wird. Woran liegt es, dass sie ab einem bestimmten Durchlauf extrem langsam wird? Hat jemand eine Idee?


Linus
Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 69
Anmeldedatum: 30.08.10
Wohnort: Aachen
Version: ---
     Beitrag Verfasst am: 07.09.2010, 19:23     Titel:
  Antworten mit Zitat      
Probleme durch fehlendes Preallocating ("variablen vordefinieren") sehen meistens schon so ähnlich aus, aber du bist dir ja sicher, dass es das nicht sein kann?

Ist das display(x) wirklich notwendig? Das ist immer sehr langsam...
[Edit] Ah, sehe gerade du hast das zu Debug-Zwecken drin. Würd ich so nicht tun, messe die Zeit echt lieber mit tic und toc, wenn du das brauchst... [/Edit]

Kennst du den Profiler? Ein absolut super Tool! Im Editor unter Tools, Open Profiler. Probier das mal für mehrere Werte aus und schau, ob du daraus schlau wirst!
_________________

RWTH - Mindstorms NXT Toolbox - free & open source
Private Nachricht senden Benutzer-Profile anzeigen
 
gast

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 07.09.2010, 21:13     Titel: danke
  Antworten mit Zitat      
Danke für die Antwort. Habe mir den Profiler angeschaut - eine sehr nützliche Funktion.

Leider sehe ich immernoch nicht, warum die Durchläufe ab einem bestimmten Zeitpunkt langsam werden.

Es scheint ein prozentualer Anteil der Schleife schnell durchzulaufen (unabhängig von F). Gibt man F=100 ein, sind die Durchläufe die für F=10 nötig wären nach einigen Sek durch. Gibt man F=10 ein, dauert es wieder ewig.

Ich kann es mir nicht erklären.
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 07.09.2010, 22:09     Titel: Re: for-Schleife - Zeit der Durchläufe nimmt plötzlich zu
  Antworten mit Zitat      
Hallo Gast,

bitte poste den kompletten Code mit den fest vorgegebenen v, b, L. Dann könnten wir das ebenfalls laufen lassen und die Ursache der merkwürdigen Geschwindigkeitsänderungen finden.
Sind auch w und z ebenfalls ordnungsgemäß pre-allociert?
Was ist "v"?!
Wir können solche wichtigen Details nicht erraten.

Dies sieht nicht so aus, als könne es überhaupt laufen:
gast hat Folgendes geschrieben:
Code:

s(v+x*5-4:v+x*5) = [20+x 50+x 55+x];
 


Dise läßt sich deutlich beschleunigen:
Code:
wz = ones(1,4) * (-1);
w(v + x*5-4:v + x*5) = wz;

Besser:
Code:
w(v + x*5-4:v + x*5) = -1;


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

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 08.09.2010, 01:35     Titel: danke
  Antworten mit Zitat      
Ich bin euch dankbar für eure Bemühungen. Hier der Code der Funktion (genauer der Teil, der langsam läuft). Ich habe die verschachtelte Schleife etwas umgeschrieben, weil ich gelesen habe, dass solche Schleifen langsam sein können. Nun ist es "nur" eine for-Schleife - das Problem ist aber geblieben. Ab einem bestimmten Punkt wirds deutlich langsamer (bei mir z.B. bei F=80 ab x ~ 139000)...

Code:
function [z,w,s] = testen(F)

Laenge_s = 25 + F*364*24 + F*364 + 25 + F*364*24 + F*(90-1) + F*91 ...
    + F*92 + F*92 + 25 + 25 + 2*F*364*24 + 2*F*364 + 24*5 + F*364*24;
b = zeros(10192*F+4,1);
z = zeros(Laenge_s,1);
w = z;
s = z;

u_II = [0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0];

i3 = 731 * F + 124;
i4 = 9467 * F + 124;
i5 = 18203 * F + 124;
i6 = 26939 * F + 124;
i7 = 35675 * F + 124;

L = ones(365,24);

Bed = 116485;
v = 2912220;
d = 5;
h = 6;

for x = 1 : 364*24*F            
            z(v + x*5-4 : v + x*5) = Bed + x;
            s(v + x*5-4 : v + x*5) = [i3+x i4+x i7+x i5+x i6+x];
            w(v + x*5-4 : v + x*5) = [ones(1,4)*(-1) (-1)*u_II(h)];
            b(Bed + x) = - L(d,h);
end


Bin für jede Hilfe dankbar.
 
Gast

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 08.09.2010, 02:01     Titel: oh mann
  Antworten mit Zitat      
Das umschreiben und kopieren des Codes für das Forum hat mich den Fehler tatsächlich erkennen lassen. Der Abdruck meiner rechten Handfläche wird noch einige Zeit auf meiner Stirn sichtbar sein.

Meine Vorbelegung der Vektoren s,w,z ist einfach falsch - die Länge ist zu kurz. Im Laufe der Schleife wird x irgendwann größer als der maximale Index dieser Variablen. Es kommt zur Längenänderung in jeder Iteration und damit natürlich zur Verlangsamung.

Am Ende ist es ein dummer simpler Denkfehler. Ich danke euch allen für die Hilfe. Ich denke, der Fehler kann nun behoben werden.
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 08.09.2010, 14:50     Titel: Re: danke
  Antworten mit Zitat      
Hallo Gast,
Code:

for x = 1 : 364*24*F            
            z(v + x*5-4 : v + x*5) = Bed + x;
            s(v + x*5-4 : v + x*5) = [i3+x i4+x i7+x i5+x i6+x];
            w(v + x*5-4 : v + x*5) = [ones(1,4)*(-1) (-1)*u_II(h)];
            b(Bed + x) = - L(d,h);
end


Du kannst diese Schleife noch deutlich beschleunigen:
1. berechne "v+x*5-4" und "v+x*5" nur einmal und speicher sie temporären Variablen.
2. "ones(1, 4)*(-1)" dauert deutlich länger als "[-1, -1, -1, -1]".
3. "(-1)*u_II(h)" ist wahrscheinlich langsamer als "-u_II(h)". Noch schneller könntest Du w allerdings ausserhalb der Schleife belegen:
Code:
w(:) = -1;
w(v+1:5:v+264*24*F*5) = -u_II;

4. Das gleiche gilt für die anderen Variablen. Ich würde zunächst statt des Index-Gepfriemels [5 x N] Matrizen erzeugen und sie hinterher in Vetoren umwandeln. Für s hätte man dann z.B.:
Code:
xvec = 1:364*24*F;
S = [i3 + xvec; i4 + xvec; i5 + xvec; i6 + xvec];
s(v + 1: v + 364*24*F*5) = S(:);
 

5. "b(Bed + x) = - L(d,h);" hängt gar nicht von der Schleifen-Variablen x ab??

Man könnte die Schleife also vollständig weglassen und wäre dadurch heftig viel schneller! Und die Preallociereung wäre auch überflüssig.

Übrigens ist dies nicht optimal als Pre-allocierung:
Code:
x = zeros(1, 1000);
y = x;

Zunächst wird in y nur eine "SharedDataCopy" von x gespeichert, also kein neuer Speicher allociert. Zum Glück wird das im ersten Schleife nachgeholt, so dass der Laufzeitunterschied nicht bedeutend ist.

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

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 08.09.2010, 17:56     Titel: danke
  Antworten mit Zitat      
Vielen Dank. Interessant, dass es auch so geht. Werde die Sachen umstezen.
 
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.