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

Ausführung des Files beschleunigen mit Parallel Computing T

 

LukeSkywalker
Forum-Newbie

Forum-Newbie


Beiträge: 9
Anmeldedatum: 07.01.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 08.01.2011, 10:45     Titel: Ausführung des Files beschleunigen mit Parallel Computing T
  Antworten mit Zitat      
Hallo,

ich arbeite momentan an dem Thema, wie ich die Ausführung meines Matlab Files mit der Parallel Computing Toolbox beschleunigen kann. Dazu habe ich mir zunächst die Dokumentation durchgelesen, bin jedoch nicht wirklich schlau daraus geworden, welche der aufgezeigten Möglichkeiten sinnvoll ist.

Zu Beginn meines Files werden zunächst die Variablen mit Werten bestückt, und zwar geschieht dies über eine aufgerufene Funktion, der mit einem Parameter übergeben wird, welcher Datensatz zu benutzen ist. Insgesamt gibt es 3 bzw. 4 solcher Datensätze und folglich resultieren 3 bzw. 4 Sätze der gleichen Variablen, welche lediglich verschiedene Werte tragen. Dieser Prozess sollte zum Beispiel parallel ablaufen können vermute ich.

Anschließend soll eine weitere Funktion aufgerufen werden, auch parallel mit den verschiedenen Variablensätzen. Die Auswertung der einzelnen Funktionen ist hier komplett unabhängig, können also auch gleichzeitig stattfinden.

Wie könnte ich dies realisieren? Ich dachte an das Einführen eines Scheduler objects? Indem ich erst über

Code:

sched = findResource('scheduler','type','local');
job1 = createJob(sched);
createTask(job1, @fun, 10, {bla1});
createTask(job1, @fun, 10, {bla2});
createTask(job1, @fun, 10, {bla3});
createTask(job1, @fun, 10, {bla4});
submit(job1);
 


die verschiedenen Tasks erzeuge und dann ausführe! Jedoch steht in der Doku, dass dieser Weg nicht wirklich geeignet ist, außer für Debugging und Testzwecke.

Hat irgendjemand eine Idee, wie man so etwas lösen könnte? Geht es tatsächlich über diesen Scheduler? Oder gibt es doch einen viel besseren Weg?

Ich bedanke mich schon mal im Voraus,

Gruß

LukeSkywalker
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


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

die einfachste Möglichkeit ist das Ersetzen einer for-Schleife durch eine parfor-Schleife, und das in einem MATLAB-Pool laufen zu lassen:

matlabpool open
parfor I = 1:4
%Verarbeitung des I-ten Datensatzes
end
matlabpool close

Dabei ist zu beachten, dass die Parallel Computing Toolbox in erster Linie für lang dauernde Programm ( d.h. Laufzeit >> Zeit fürs Starten einer MATLAB-Session) geeignet ist. Und dann solltest du auch darauf achten, dass dein Programm sequentiell optimal läuft (Speicher vorbelegen, vektorisieren etc.).

Kannst du mal kopieren, was da in der Doku steht? Ohne es gesehen zu haben wäre meine Vermutung, dass sich das auf den 'local' Scheduler bezieht, da hier nur die lokalen Resourcen genutzt werden und, je nach Anzahl der Rechenkerne, maximal ein Speedup von Faktor 2-4 erwartet werden kann.

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

Forum-Newbie

Forum-Newbie


Beiträge: 9
Anmeldedatum: 07.01.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 08.01.2011, 11:25     Titel:
  Antworten mit Zitat      
Guten Morgen Harald,

vielen Dank erst mal für die Antwort. Das mit der Zeit ist mir bekannt, es geht nun erst einmal darum "im Kleinen" das überhaupt zu testen, dass es natürlich eigentlich nur bei großen Datenmengen sich bemerkbar macht bzw. überhaupt einen Zeitvorteil bringt, ist mir klar. Um die Startzeit des Matlabpools z.B. geht es mir auch gar nicht, sondern nur um die reine Ausführungszeit des Skriptes, da ich davon ausgehe, dass alle Vorbereitungen (Öffnen des Matlabpools,...) schon getroffen wurden und ich nur die Zeit der Auswertung des Files benötige!

Zitat:
For jobs that require more control than the functionality offered by dfeval,
you have to program all the steps for creating and running the job. Using the
local scheduler lets you create and test your jobs without using the resources
of your cluster. Distributing tasks to workers that are all running on your
client machine might not offer any performance enhancement, so this feature
is provided primarily for code development, testing, and debugging.


Dies wäre der Abschnitt, und da vor allem der letzte Satz! Aber, wie du schon sagst, bezieht sich das auf den local Scheduler. Ich kann leider mit den Dingen noch nicht sehr viel anfangen, was das genau bedeutet.

Die parfor-Schleife ist natürlich in der Doku gleich zu Beginn sogar auch erwähnt. Die könnte man sogar eventuell für diesen Fall anwenden, stimmt. Dies könnte man für die Initialisierung der Variablen und der Ausführung der danach folgenden Funktion verwenden, werds gleich mal testen!

Gruß

LukeSkywalker
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


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

das bezieht sich wie vermutet auf den local Scheduler. Wenn du z.B. einen Dual-Core Rechner nutzt und da verteilst, hast du zwar zwei Rechenkerne aber nicht doppelt soviel Hauptspeicher, doppelt so viel Cache etc. Wenn es also nicht die Geschwindigkeit des Kernes, sondern Speicherzugriffe oder ähnliches sind, die das Programm ausbremsen, dann bringt diese lokale Parallelisierung unter Umständen nichts. Dann müsste man auf mehrere Rechner gehen (in Verbindung mit MATLAB Distributed Computing Server).

Fragen:
wie viele Cores hat dein Rechner?
welches Release nutzt du?

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

Forum-Newbie

Forum-Newbie


Beiträge: 9
Anmeldedatum: 07.01.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 08.01.2011, 12:10     Titel:
  Antworten mit Zitat      
Hallo,

zunächst einmal hat mein Rechner 2 Cores, zu Testzwecken könnte ich aber auch auf einen Rechner mit 4 Cores zugreifen, aber so jetzt erstmal nur 2, Release ist 2009a.

Bin nun bei der Implementierung der parfor-Schleife, doch irgendwie will das nicht recht funktionieren, bin auch leider noch kein Matlab-Experte, arbeite erst seit ein paar Monaten überhaupt damit.

Wenn ich die Initialisierungsfunktion (inifun genannt) 3 Mal aufrufen lassen wollen würde, jeweils mit verschiedenen Paramtern, wie könnte ich das machen?

Vorher sah der Code in etwa so aus:

Code:

[a1,b1] = inifun(@handle1,k,v1);
[a2,b2] = inifun(@handle2,k,v2);
[a3,b3] = inifun(@handle3,k,v3);
 


und das könnte ich ja in eine parfor-Schleife umbauen, doch wie bekomm ich es hin, dass das i (welches ja die Werte 1, 2 und 3 annimmt) an die Variablennamen angehängt wird?

Ich bin mir sicher, dass das irgendwie machbar ist, doch leider stehe ich da momentan etwas auf dem Schlauch, wie das gehen kann. Befehle wie ai funktionieren natürlich nicht.

Hast du dafür ne Idee?

Gruß

LukeSkywalker
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


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

hier ein Beispiel:
Code:
matlabpool open 2
fh = {@sin, @cos, @tan};
in = reshape(1:9, 3, 3);
out = zeros(3,3);
parfor I=1:3
   f = fh{I};
   out(I,:) = f(in(I,:));
end
matlabpool close


Leichter (und auch im Sinne des Erfinders) wäre es allerdings, wenn immer dieselbe Funktion ausgeführt wird.

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

Forum-Newbie

Forum-Newbie


Beiträge: 9
Anmeldedatum: 07.01.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 08.01.2011, 13:26     Titel:
  Antworten mit Zitat      
Hallo,

vielen Dank für diesen Ansatz, habe versucht, den auf meinen Fall anzupassen, doch leider taucht noch ein Fehler auf, ich poste mal meinen Versuch:

Code:

matlabpool open 2
fh = @inifun;
in = reshape(1:9,3,3); % für 3 Funktionen mit je 3 Eingängen
out = zeros(3,2); % jeweils 2 Rückgabewerte pro Gleichung

% Jetzt müssen ja noch die Eingänge belegt werden:

in(1,:) = [@handle1, k, v1];   % xx
in(2,:) = [@handle2, k, v2];
in(3,:) = [@handle3, k, v3];

parfor I=1:3
f = fh;
out(I,:) = f(in(I,:));
end

matlabpool close
 


Jedoch meckert er schon in der mit xx kommentierten Zeile, dass er da kein Function handle vertragen kann. Die Sache ist ja, die Funktion ist im Grunde immer gleich, doch dieser (immer gleichen) Funktion werden verschiedene Function-Handles und verschiedene Parameter übergeben.

Wie gesagt, selbst wenn der Aufwand, den man hier betreiben muss, für diese 3 parallelen Schritte nicht sinnvoll ist, macht das nichts, denn es soll später auf größere Mengen übertragen werden.

Es sei denn natürlich, es gäbe wirklich konkrete Einsprüche, warum das Parallelisieren überhaupt gar keinen Sinn macht, aber ich denke es lässt sich schon ein Zeitvorteil erzielen (wenn man von der Startzeit für den Matlabpool absieht).

Gruß,

LukeSkywalker
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


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

du kannst nicht in ein Array verschiedene Datentypen unterbringen.
Leg doch drei getrennte Eingansarrays an:

Code:
matlabpool open 2

out = zeros(3,2); % jeweils 2 Rückgabewerte pro Gleichung

% Jetzt müssen ja noch die Eingänge belegt werden:

in1 = {@handle1, @handle2, @handle3};   % xx
in2 = k;
in3 = {v1; v2; v3}
out1 = cell(1,3);
out2 = cell(1,3);

parfor I=1:3
[out1{I}, out2{I}] = inifun(in1{I}, in2, in3{I});
end

matlabpool close


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

Forum-Newbie

Forum-Newbie


Beiträge: 9
Anmeldedatum: 07.01.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 09.01.2011, 10:06     Titel:
  Antworten mit Zitat      
Guten Morgen Harald,

hab das nun gerade einmal ausprobiert und es funktioniert tatsächlich prima!! Vielen Dank für die Hilfe!!

Werde dann mal weiter an dem Programm arbeiten und mich dann noch mal melden, ob alles geklappt hat mit der Parallelisierung des nachfolgenden Codes. Aber ich hoffe, mit deinen tollen Ansätzen bekomm ich nun auch den Rest umgeschrieben!

Nochmal vielen Dank soweit für deine Mühe

Gruß LukeSkywalker
Private Nachricht senden Benutzer-Profile anzeigen
 
LukeSkywalker
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 9
Anmeldedatum: 07.01.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 09.01.2011, 17:50     Titel:
  Antworten mit Zitat      
Hallo nochmal,

versuche gerade die parfor-Konstruktion auf einen weiteren Fall anzuwenden, nämlich in Verbindung mit einer while-Schleife. Dies scheint so leider nicht so ganz zu funktionieren. Grob sieht der Aufbau so aus:

Code:


a = {0, 0, 0}
b = {0, 0, 0}

parfor I=1:3
while a{I} < c   % c ist vorher schon festgelegt worden
  [out2{I}, a{I}] = f(out1{I},out2{I});
end % while
% hier stehen dann noch Besetzungen der Variable b usw.
end % parfor
 


der Wert a wird dabei innerhalb der Funktion verändert, und solange der Wert c nicht erreicht ist, soll die Funktion f ausgeführt werden. Out2 wird auch in jedem Funktionsaufruf verändert. Doch nun zum Problem:

Gemeckert wird folgendermaßen:
Zitat:

Error: The variable a in a parfor cannot be classified.
See Parallel for Loops in MATLAB, "Overview".


Hab dann herausgefunden, dass man evtl. den Wert in einer parfor-Schleife nicht so einfach überschreiben kann, also neue Variablen eingefügt und den Code abgeändert:

Code:

a = {0, 0, 0};
a2 = {0, 0, 0};
b = {0, 0, 0};
out3 = cell(1,3);

parfor I=1:3
while a{I} < c   % c ist vorher schon festgelegt worden
  [out3{I}, a2{I}] = f(out1{I},out2{I});
  a{I} = a2{I};
  out2{I} = out3{I};
end % while
% hier stehen dann noch Besetzungen der Variable b usw.
end % parfor
 


Aber auch das funktioniert nicht, nun kann die Variable a2 nicht klassifiziert werden! Mit einer normalen for-Schleife hingegen klappt der Code einwandfrei.

Ich weiß leider nicht mehr woran es liegen könnte.

Weiß einer Rat?

Vielen Dank schonmal

Gruß LukeSkywalker
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


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

es scheint, dass parfor Cell Arrays in dieser Form nicht mag.
Versuch es doch so, dass du a als double array nimmst:

Code:
a = [0, 0, 0];
b = {0, 0, 0}

parfor I=1:3
while a(I) < c   % c ist vorher schon festgelegt worden
  [out2{I}, a(I)] = f(out1{I},out2{I});
end % while
% hier stehen dann noch Besetzungen der Variable b usw.
end % parfor


Dasselbe für andere Variablen, bei denen es auch Probleme gibt.
Wenn es um Vektoren geht, die aber immer die gleiche Länge haben, kann man mit Spalten von Matrizen arbeiten statt Elementen eines Vektors.

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

Forum-Newbie

Forum-Newbie


Beiträge: 9
Anmeldedatum: 07.01.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.01.2011, 10:13     Titel:
  Antworten mit Zitat      
Guten Morgen,

dies funktioniert leider auch nicht, immer noch der selbe Fehler! Der Wert a ist eigentlich auch bloß ein Skalar, out2 die vorher während der Initialisierung belegte Struktur, die halt bei jedem Funktionsaufruf dann verändert wird. Woran das bloß liegen könnte, dass er immer noch sagt

Zitat:
??? Error: The variable a in a parfor cannot be classified.
See Parallel for Loops in MATLAB, "Overview".


Aber theoretisch sollte so eine Verschachtelung einer while Schleife in eine parfor-Schleife doch machbar sein oder nicht?

Hab experimentellerweise mal einfach die while-Schleife weggelassen und folgenden Code getestet:

Code:

a = {0, 0, 0}
b = {0, 0, 0}

parfor I=1:3
% while a{I} < c   % c ist vorher schon festgelegt worden
  [out2{I}, a{I}] = f(out1{I},out2{I});
% end % while
% hier stehen dann noch Besetzungen der Variable b usw.
end % parfor
 


Der Code gibt die Fehlermeldung für out2 an, dass die Variable nicht klassifiziert werden kann. Ersetzt man out2 durch out3, funktionierts so!

Daraus entnehme ich, dass die parfor-Schleife nicht in der Lage ist, einen Wert zu berechnen und in die selbe Variable zu schreiben. Einen Fehler für das a gibts hier auch nicht, da die Abfrage wegen a entfällt. An den Cells liegt es jedenfalls nicht!

Was könnte man tun, um trotzdem die while-Schleife zu implementieren? Da muss es doch einen Weg geben...

Gruß LukeSkywalker

Edit: Also While-Schleifen ansich gehen schon, hab nun die Abfrage einfach geändert zu

while 0 < c

dann meckert er nicht, sondern landet logischerweise in einer Endlosschleife. Das Problem liegt auf jeden Fall dadrin, dass er den durch die Funktion sich ergebenden Wert a nicht zuordnen kann irgendwie. Find ich komisch, weil das in einer normalen for-Schleife klappt. Und sobald ich dann out2{I} = out3{I} setze, damit die Funktion beim zweiten Aufruf die Werte der Ausgabe des ersten Funktionsaufrufes erhält, gibts auch nen Fehler, dass out2 nicht mehr klassifiziert werden kann. Irgendwie recht blöd alles.
Private Nachricht senden Benutzer-Profile anzeigen
 
LukeSkywalker
Themenstarter

Forum-Newbie

Forum-Newbie


Beiträge: 9
Anmeldedatum: 07.01.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.01.2011, 17:17     Titel:
  Antworten mit Zitat      
Okay, es hat sich erledigt!!! Die von dir geposteten Möglichkeiten funktionieren in der Tat, es handelt sich dabei um einen Fehler in Matlab, welcher erst ab der 2010er Version behoben wurde. Ab 2010a funktioniert es so wie du beschrieben hast!!

Vielen Dank nochmal für deine Hilfe

Gruß LukeSkywalker
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


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

noch eine Anmerkung:
nicht jede for-Schleife ist in eine parfor-Schleife umwandelbar; insbesondere nicht, wenn die Iterationen in irgendeiner Form voneinander abhängen oder aufeinander aufbauen.
Die Iterationen einer parfor-Schleife können potentiell auch auf verschiedenen Rechnern ausgeführt werden, und das bringt gewisse Einschränkungen mit sich.
Die Parallel Computing Toolbox ist eines der neueren Produkte in MATLAB, und daher finden dort verhältnismäßig viele Weiterentwicklungen und auch Verbesserungen statt, und es ist empfehlenswert, ein aktuelles Software-Release zu verwenden.

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

Forum-Newbie

Forum-Newbie


Beiträge: 9
Anmeldedatum: 07.01.11
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.01.2011, 14:18     Titel:
  Antworten mit Zitat      
Hallo nochmal,

ja, dass gewisse Kriterien erfüllt sein müssen, damit die parfor-Schleife anwendbar ist, ist mir bekannt. Das ist in meinem konkreten Fall jedoch gar kein Problem, da die zu bearbeitenden Funktionen absolut unabhängig voneinander sind.

Das Problem, was jetzt auftritt, ist jedoch, dass die Ausführung mit dieser parfor-Schleife sehr sehr viel länger dauert als das Lösen des Problems auf nur einem Kern. Ich habe nun der Einfachheit halber erst einmal nur 2 parallele Aufgaben genommen. Die habe ich mit einer normalen for-Schleife und ohne matlabpool gelöst. Anschließend habe ich sie mit der entwickelten parfor-Schleife gelöst mit matlabpool (2 Kerne -> 2 Worker). Die Zeit, die das Skript zur Ausführung benötigt, ist nun 5 mal so hoch. Wie kann das sein?! Das Öffnen des matlabpools sowie das Schließen sind da nicht mit eingerechnet, die reine Arbeitszeit beträgt tatsächlich 5 mal so viel. Ich habe mich über den Taskmanager auch vergewissert, dass tatsächlich beide Kerne aktiv sind, bei dem Lösen mit einem Kern besitzt der Rechner eine Prozessorauslastung von 50% (1 von 2 Kernen arbeitet), nach dem Öffnen des matlabpools und der parfor-Schleife liegt die Prozessorauslastung bei etwa 90%.

Wie kann es sein, dass die Ausführung so viel länger dauert? Beide parallel ablaufenden Prozesse greifen zwar auf die selbe Funktion zu, aber das sollte ja nicht das Problem sein oder? Matlab sollte sich intern doch Kopien der Funktionen anlegen, um die getrennt voneinander durchlaufen zu können, oder nicht? Weil sonst wäre das Prinzip einer parfor-Schleife ja irgendwie sinnlos...

Hat einer von euch eine Idee, woran so etwas liegen kann?

Gruß

LukeSkywalker
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen

Gehe zu Seite 1, 2  Weiter

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 - 2024 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.