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

Parfor-Schleifen und ein Probleme mit der Indizierung

 

PeterK
Forum-Anfänger

Forum-Anfänger


Beiträge: 27
Anmeldedatum: 23.12.13
Wohnort: Hamburg
Version: ---
     Beitrag Verfasst am: 09.07.2014, 17:18     Titel: Parfor-Schleifen und ein Probleme mit der Indizierung
  Antworten mit Zitat      
Hallo alles zusammen,

durch die Verwendung von Parfor-Schleifen konnte ich meinen Code um den Faktor 3 in Ausführungsgeschwindikeit steigern.

Nun habe ich allerdings ein Problem mit der Indizierung der Eingabe und Ausgabeparameter.

Auf das Problem reduziert sieht mein Code so aus:

Code:
x=[1:1:10];

parfor i=1:10

    for j=1:length(x)
 
    x(j+1)=x(j);
   
    end
   
   
end


Der Parfor-Loop rechnet voneinander komplett unabhängige Schleifen. In jeder dieser Schleife ist nun eine weitere normale for-Schleife, wobei das Ergebnisse für die Schleifen-Nummer j als Eingabewert für die Schleifen-Nummer j+1 dienen soll.

Wenn ich die Parfor-Schleife durch eine for-Schleife erstetze, dann funktioniert alles. Mit der Parfor-Schleife bekomme ich die Fehlermeldung:

"Error: The variable x in a parfor cannot be classified."

Eigentlich denke ich, dass das alles auch mit der Parfor-Schleife gehen sollte weil die Parfor-Schleifen ja weiterhin noch komplett voneinander unabhängig sind. Nur die "innere For-Schleife" hat eine Abhängigkeit, aber die wird ja auch nicht parallel sondern seriel berechnet. Eventuel muss ich da vielleicht irgendwo die Indexierung anders definieren?

Kann mir da jemand hier bei diesem Problem weiter helfen?
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 09.07.2014, 19:43     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
Der Parfor-Loop rechnet voneinander komplett unabhängige Schleifen.

Es mag zwar sein, dass die Ausführungsreihenfolge der Schleifen egal ist - sie sind ja nicht von i abhängig. Die einzelnen Iterationen sind aber sehr wohl voneinander abhängig: wenn x(j+1) auf x(j) gesetzt werden soll, muss x(j) ja bekannt sein - das ist aber das Ergebnis der vorherigen Iteration.

Zitat:
durch die Verwendung von Parfor-Schleifen konnte ich meinen Code um den Faktor 3 in Ausführungsgeschwindikeit steigern.

Dazu muss es ja funktioniert haben. Ist diese Frage nun ein anderes Problem, oder Teil dieses Problems?

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
PeterK
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 27
Anmeldedatum: 23.12.13
Wohnort: Hamburg
Version: ---
     Beitrag Verfasst am: 10.07.2014, 11:09     Titel:
  Antworten mit Zitat      
Nein das ist noch das selbe Problem.

In meinem eigentlichen Code wird in der for-schleife eine Funktion ausgeführt und wenn ich die berechnneten Werte der Funktion nicht wieder zürück gebe sondern einfach "verfallen" lasse, dann kann ich den Code trotzdem ausführen um zu schauen wie schnell er nun läuft. Nur ist das dann natürlich blödsinnig, da ich ja die Berechneten Werte zum Schluss ja eigentlich haben möchte Smile Es geht also eigentlich nur darum wie ich die berechneten Werte "heraus" aus den Schleifen bekomme.

Der Code sieht also dann eigentlich etwa so aus:

Code:
x=[1:1:10];

parfor i=1:10

    for j=1:length(x)
 
    [x(j+1)]=function(x(j));
   
    end
   
   
end


Wenn ich nun die Ausgabewerte der function nicht ausgebe, dann kann ich die Berechnung trotzdem ausführen.

Sorry für die Verwirrung zuvor. Ich wollte den Code im ersten Post soweit vereinfachen wie möglich, aber vielleicht war das schon zu viel des guten Smile

Kannst du mir einen Tip geben, wie ich den Code umschreiben müsste, damit er funktioniert?

Viele Grüße!
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 10.07.2014, 11:18     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
Wenn ich nun die Ausgabewerte der function nicht ausgebe, dann kann ich die Berechnung trotzdem ausführen.

Aber der Code macht dann etwas anderes. Wenn du x nicht aktualisierst, wird einfach nur viele Male das gleiche ausgeführt.

In deinem Beispiel:
Code:
x=[1:1:10];
for i=1:10
    for j=1:length(x)
    (x(j));
    end
end

Hier wird x nicht verändert.

Code:
x=[1:1:10];
for i=1:10
    for j=1:length(x)
    x(j+1) = (x(j));
    end
end

Hier wird x von Schleifendurchgang zu Schleifendurchgang verändert.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
PeterK
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 27
Anmeldedatum: 23.12.13
Wohnort: Hamburg
Version: ---
     Beitrag Verfasst am: 10.07.2014, 11:47     Titel:
  Antworten mit Zitat      
Danke für die schnelle Antwort. Ja , da hast du recht, dass die Codes nun nicht genau das gleiche tun, da ich die Eingabeparameter nicht aktualisiere.

Für eine reine Geschwindigkeitsanalyse ist das ok um zu sehen wie viel schneller der Code nun mit der Parfor-Schleife läuft, aber letztlich muss ich die Eingabeparameter natürlich aktualisieren und auch irgendwie abspeichern (im Beispiel als x(j+1)-Werte). Und damit habe ich ja das Problem.
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 10.07.2014, 12:37     Titel:
  Antworten mit Zitat      
Hallo,

um das gewünschte zu erreichen, muss eine Iteration die Ergebnisse der vorherigen nutzen. Damit ist das in der momentanen Form nicht parallelisierbar.

Vielleicht lässt sich der Code auf einer anderen Ebene (also z.B. innerhalb dieser Funktion) parallelisieren?

Je genauer du dein Projekt beschreiben kannst, desto eher kann man helfen.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
PeterK
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 27
Anmeldedatum: 23.12.13
Wohnort: Hamburg
Version: ---
     Beitrag Verfasst am: 10.07.2014, 17:26     Titel:
  Antworten mit Zitat      
Hmmm.... ich glaube ich habe mich nicht korrekt ausgedürckt. Vielleicht fangen wir nochmal von Null an. Sorry!

Ich habe gerade gemerkt, dass folgendes funktioniert:

Code:


parfor i=1:10

    for j=1:10
 
    [x]=function(x);
   
    end  
   
end


Innerhalb des j-Loops wird wird also ein Anfangswert von x eingelesen und dann innerhalb des j-Loops geupdatet und neu berechnet. Und am Ende des j-Loops bekomme ich den Endwert von x und kann darauf in meinem Matlab Workspace zugreifen. Grundsätzlich ist das schon mal das wichtigste.

Jetzt würde ich nun allerdings auch gerne die Zwischenwerte von x abspeichern, also in der Form:

Code:


parfor i=1:10

    for j=1:10
 
    [x(j+1)]=function(x(j));
   
    end  
   
end


Und das geht leider nicht. Gut möglich dass obige Syntax nicht ganz korrekt ist, aber ich hoffe es ist klar was ich meine Smile

Die Berechnung als solche funktioniert also (da ich das Endergebnis von x am Ende des j-Loops bekomme), nur brauche ich nun noch irgendwie Zugriff auf die x(j) Zwischenwerte.
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 10.07.2014, 20:08     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
Ich habe gerade gemerkt, dass folgendes funktioniert:

Und was ist function dabei? Folgendes Beispiel funktioniert bei mir z.B. nicht:
Code:
x = 1:10;

parfor i=1:10

    for j=1:10
 
    [x]=sin(x);
   
    end  
   
end


Zitat:
Gut möglich dass obige Syntax nicht ganz korrekt ist, aber ich hoffe es ist klar was ich meine

Leider nicht. Das, was die Syntax bewirkt, geht ja nunmal nicht. Wenn du an sich etwas anderes bewirken möchtest, dann ist mir nicht klar, was.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
PeterK
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 27
Anmeldedatum: 23.12.13
Wohnort: Hamburg
Version: ---
     Beitrag Verfasst am: 11.07.2014, 00:23     Titel:
  Antworten mit Zitat      
Hallo,

ja da hast du natürlich recht. Also folgend kommt der Code, diese Mal voll funktionsfähig, aber tortzdem auf das nötigste reduziert Smile

Code:
parfor i=1:10
 
    x=1

    for j=1:10

    [Output_value(j,i),x]=Test_function(x); % Einlesen von x in die Test-Funktion. Ausgabe ist u.a. ein ge-updatetes x für die nächste loop-Iteration.
       
    end
   
   
end


wobei die Funktion "Test_function" folgend aussieht:

Code:

function [Output_value,x] = Test_function(x)

Output_value=x*2; % Berechnung und Rückgabe eines Ausgabewertes
x=x+1; % updaten und Rückgabe des x-Wertes

end
 


Hier passiert also genau das was ich möchte, und zwar wird ein anfänglicher x-Wert (hier x=1) in die Funktion "Test_function" eingelesen und damit in der Funktion
1. ein Ausgabewert berechnet (genannt "Output_value") und
2. ein neuer Wert für x berechnet welcher ebenfalls zurück zum Skript zurück gegeben wird um dann in der nächsten Schleifenwiederholung als neuer x-Wert eingelesen zu werden.

Nach dem kompletten Durchlauf des Skripts habe ich dann Zugriff im Matlab Workspace auf alle berechneten "Output_values".

Leider habe ich aber keinen Zugriff auf die x-Werte, da der zurückgegebene x-Wert (kommend von Test_function) den alten x-Wert einfach überschreibt.
Das Problem ist nun also wie bekomme ich die Indizes für die x-Werte so gesetzt, dass ich darauf nach dem Durchlauf des Skripts Zugriff habe?

Wenn ich das über zwei for-Schleifen realisieren würde, dann sähe es so zum Beispiel so aus:

Code:

x(1:10)=1;

for i=1:10
 
    for j=1:10

    [Output_value(j,i),x(j+1,i)]=Test_function(x(j,i));
       
    end
     
end
 


Aber der Code läuft halt deutlich langsamer, da nicht auf mehreren Prozesorenkernen.

Die Frage ist also, wie ich den ersten Code so umschreiben kann, dass ich ebenfalls die x-Werte heraus bekomme, so wie es der zweite Code mit den beiden for-Schleifen macht?
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 11.07.2014, 09:03     Titel:
  Antworten mit Zitat      
Hallo,

dann sind ja aber alle Spalten gleich. Ist das wirklich Sinn der Sache?

Versuche mal, die innere for-Schleife noch in eine Funktion zu packen. Das sollte helfen. Siehe auch "Deeper Insights into Using parfor" von
http://www.mathworks.de/products/pa.....-computing/tutorials.html

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
PeterK
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 27
Anmeldedatum: 23.12.13
Wohnort: Hamburg
Version: ---
     Beitrag Verfasst am: 12.07.2014, 12:43     Titel:
  Antworten mit Zitat      
Naja, das war nur ein "Dummy-Code" der das Problem aufzeigen sollte. Der gesamte Code wäre zu unübersichtlich. Smile

Also ich habe es nun doch noch geschafft, auch ohne weitere Unterfunktion.

Der "Trick" ist:

1. Die Variablen-Matrix "x"mit richtigen Dimension vordefinieren (Interesanterweise muss meine Variable "Output_value" nicht vordefiniert werden!)

2. Der For-Schleife nur Slices von "x" übergeben

3. Am Ende jeder For-Schleife die Slices an die richtige Position der x-Matrix speichern.

Der funktionierende Code sieht also folgendermaßen aus:

Code:

x(11,10)=1;

parfor i=1:10
    x_in_loop=x(:,i)
 
    for j=1:10

    [Output_value(j,i),x_in_loop(j+1)]=Test_function(x_in_loop(j));
       
    end
   
    x(:,i)=x_in_loop
   
end


Damit bekomme ich nun auch die Zwischenwerte für x aus den Schleifendurchläufen heraus. Macht irgendwie Sinn so im Nachhinein, nachdem man sieht wie es aussehen soll Smile
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.