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

Messsystem: parallelisieren / performance steigern

 

Anfänger 2.0
Forum-Anfänger

Forum-Anfänger


Beiträge: 37
Anmeldedatum: 17.10.13
Wohnort: kreis Karlsruhe
Version: ---
     Beitrag Verfasst am: 10.09.2014, 09:48     Titel: Messsystem: parallelisieren / performance steigern
  Antworten mit Zitat      
Hi Leute,

ich habe eine GUI mit Graphen, die per Button eine m-File startet.
diese m-File steuert verschiedene Geräte ( z.B. NWA ) an.
Nach der Initialisierung wird in einer While Schleife Messungen durchgeführt und geplottet.
Im Moment messen und berechnen wir mit einer Geschwindigkeit von etwa 0,9 Sekunden pro Schleifendurchlauf.
Das soll nach Möglichkeit perfektioniert werden.
Tests haben ergeben, dass das NWA mit 0,45-0,5 Sekunden mit Abstand am längsten für seinen "Job" braucht. Die anderen Geräte liegen bei 0,1 und 0,05 Sekunden "Topspeed".

Nun war unsere Idee, das ganze zu Parallelisieren. Und zwar am besten das NWA (da es ja bekanntlich am längsten braucht) mit einem Kern ansteuern und alles andere mit dem anderen Kern.

Da ich nie mit Parallelisierung gearbeitet habe, weiß ich nun nicht ob und wie das in Matlab funktionieren würde.
Natürlich werde ich mich jetzt auch nebenbei einlesen und etwas an kleineren Programmen herumprobieren.

Ich freue mich auf eure Hilfe und Tipps.

Freundliche Grüße
euer Anfänger Wink
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: 12.09.2014, 12:59     Titel:
  Antworten mit Zitat      
Hallo,

dürfte wenn am besten mit der Parallel Computing Toolbox und SPMD klappen. Videos dazu gibts hier:
http://www.mathworks.de/products/pa.....-computing/tutorials.html
Darauf achten: auch Kommunikation kostet Zeit. Im Extremfall kann es passieren, dass der parallelisierte Code langsamer ist als das Original.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Anfänger 2.0
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 37
Anmeldedatum: 17.10.13
Wohnort: kreis Karlsruhe
Version: ---
     Beitrag Verfasst am: 15.09.2014, 09:13     Titel:
  Antworten mit Zitat      
hallo harald, danke für deine Antwort..

Befehle wie
Code:
bringen mir wenn ich das richtig verstanden habe leider nichts,
da ich keine festen Variablen in meiner Schleife habe die parallel abgearbeitet werden können.
Mit jedem Schleifendurchlauf werden Messgeräte angesprochen, deren Rückgabewerte dann im nächsten Schleifendurchlauf gebraucht werden.


Dieses batch habe ich noch nicht ganz verstanden.
Kann ich theoretisch den Befehl für das NWA, welches ja zu lange braucht, per batchjob ausführen und der wird dann parallel bearbeitet und die restliche Schleife arbeitet weiter?
Und wenn die Rückgabe des NWA gebraucht wird kann ich ja ein
Code:
wait(job,'finished');
verwenden.

Und was genau hat es mit diesem parpool auf sich?
Kann ich bspw. mit parpool(2) zwei Instanzen erstellen und für jeden Befehl angeben in welcher Instanz er ausgeführt werden soll?

Gruß
der Anfänger Shocked
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: 15.09.2014, 10:01     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
da ich keine festen Variablen in meiner Schleife habe die parallel abgearbeitet werden können.
Mit jedem Schleifendurchlauf werden Messgeräte angesprochen, deren Rückgabewerte dann im nächsten Schleifendurchlauf gebraucht werden.

Das verstehe ich nicht. Am besten ein konkretes Code-Beispiel.
spmd ermöglicht dir, gezielt in einer Session bestimmten Code auszuführen. Das sollte also alles sein, was du brauchst.

Zitat:
Kann ich theoretisch den Befehl für das NWA, welches ja zu lange braucht, per batchjob ausführen und der wird dann parallel bearbeitet und die restliche Schleife arbeitet weiter?

Theoretisch ja, praktisch nein: um das zu machen, muss für jeden batch-Aufruf erst im Hintergrund eine MATLAB-Session gestartet werden, und das dauert ca. 10 Sekunden.

Zitat:
Kann ich bspw. mit parpool(2) zwei Instanzen erstellen und für jeden Befehl angeben in welcher Instanz er ausgeführt werden soll?

Mit parfor werden automatisch die Iterationen einer for-Schleife ausgespaltet, mit spmd kann man in Kombination mit labindex angeben, was in welcher Instanz ausgeführt werden soll.
Es ist nicht notwendig, explizit einen parallel pool zu starten, wenn man mit spmd oder parfor arbeitet, da das (zumindest mit Standardeinstellungen) automatisch geschieht. Der einzige Vorteil von parpool ist, dass der parallel pool so schon vorab gestartet werden kann.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Anfänger 2.0
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 37
Anmeldedatum: 17.10.13
Wohnort: kreis Karlsruhe
Version: ---
     Beitrag Verfasst am: 15.09.2014, 12:58     Titel:
  Antworten mit Zitat      
Hmm dan habe ich spmd wohl nicht wirklich verstanden.
Ja dass batch 10 sekunden braucht habe ich gemerkt Very Happy war wohl der falsche Ansatz.
Hab mal einen beispielhaften Code geschrieben der so etwa den Ablauf darstellt. Die Pausen sind eingebaut um die "Reaktionszeit" der jeweiligen Geräte zu simulieren.
Den Bereich der möglichst Parallel laufen soll habe ich mit Kommentarzeilen "eingeklammert"

Hoffe du kannst damit was anfangen.

Grüße
der Anfänger Very Happy

Code:

i = 1;
t = zeros(1,20000);
inc = zeros(1,20000);
ref = zeros(1,20000);
temp = zeros(1,20000);
value = zeros(1,20000);
value(1) = 1.5;
Flag = evalin('base','Flag');
startTime = clock;

while Flag == 1
    tic

    if i > 1
       
        Mat = round((rand(100,100).*100));
        pause(0.2);
        marker1 = round(rand(1)*100);
        marker2 = round(rand(1)*100);
       
        if marker1 == 0
            marker1 = marker1 + 1;
        end
        if marker2 == 0
            marker2 = marker2 + 1;
        end
       
        inc(i-1) = (Mat(marker1,marker2)+NWA(1))*10;
        ref(i-1) = (Mat(marker2,marker1)+NWA(1))*10;
       
        plot(t(1:i-1),temp(1:i-1),t(1:i-1),inc(1:i-1),t(1:i-1),ref(1:i-1));
           
    end
   
    temp(i) = round(rand(1)*100)+20;
    pause(0.1);
   
    a = rand(1);
    b = round(rand(1))+rand(1);
    c = rand(1)*2;

    if i ~= 1
        value(i) = (temp(i)*a*b/2)+c;
    end

    %%%%%%%%%%%%%%%%%%%%
    NWA = rand(1,2).*value(i);
    pause(0.5)
   
    while NWA(2) < 0.5
        NWA = rand(1,2).*value(i);
        pause(0.5)
    end
    %%%%%%%%%%%%%%%%%%%%

    t(i) = etime(clock,startTime);
    Flag = evalin('base','Flag');
    i = i + 1;
   
    toc
end
 
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: 15.09.2014, 16:38     Titel:
  Antworten mit Zitat      
Hallo,

und zu was der mit % umrahmte Code nun parallel laufen?

Die usinglabindex.m zum Video "spmd: parallel code beyond parfor" kann als Template für die Verwendung von spmd mit labindex dienen.

Wenn die Daten des einen Prozesses dem anderen zur Verfügung stehen sollen, müssen sie mit labSend/labReceive geschickt werden. Ob das dann hinsichtlich Performance viel bringt, wird auf den Versuch ankommen.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Anfänger 2.0
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 37
Anmeldedatum: 17.10.13
Wohnort: kreis Karlsruhe
Version: ---
     Beitrag Verfasst am: 17.09.2014, 13:35     Titel:
  Antworten mit Zitat      
So war das mit der Parallelisierung gemeint Very Happy
Danke für deine Hilfe!
Code:



% PP = parpool;



i = 1;
t = zeros(1,20000);
inc = zeros(1,20000);
ref = zeros(1,20000);
temp = zeros(1,20000);
value = zeros(1,20000);
value(1) = 1.5;
NWAsim = 0;


startTime = clock;
spmd
    while i < 100
       
        switch labindex
            case 1
                if i > 1
                    value = labReceive(2);
                end
                NWAsim = rand(1,2).*value(i);
                pause(0.5)
               
                while NWAsim(2) < 0.5
                    NWAsim = rand(1,2).*value(i);
                    pause(0.5)
                end
                labSend(NWAsim,2);
                labBarrier
            case 2
                if i > 1
                    Mat = round((rand(100,100).*100));
                    pause(0.2);
                    marker1 = round(rand(1)*100);
                    marker2 = round(rand(1)*100);
                   
                    if marker1 == 0
                        marker1 = marker1 + 1;
                    end
                    if marker2 == 0
                        marker2 = marker2 + 1;
                    end
                   
                    inc(i-1) = (Mat(marker1,marker2)+NWAsim(1))*10;
                    ref(i-1) = (Mat(marker2,marker1)+NWAsim(1))*10;
                   
                    plot(t(1:i-1),temp(1:i-1),t(1:i-1),inc(1:i-1),t(1:i-1),ref(1:i-1));
                   
                end
               
                temp(i) = round(rand(1)*100)+20;
                pause(0.2);
               
                a = rand(1);
                b = round(rand(1))+rand(1);
                c = rand(1)*2;
               
                if i > 1
                    value(i) = (temp(i)*a*b/2)+c;
                    labSend(value,1);
                end
               
                t(i) = etime(clock,startTime);
                labBarrier
                NWAsim = labReceive(1);
        end
        i = i + 1;
    end
end

% delete(PP)
 

Hier im Beispielcode scheint das ganz gut zu funktionieren.

Ich versuche das jetzt in den richtigen Code einzubauen. Hoffentlich läuft das auch ohne weitere Probleme.
Kannst du hier mal drüber schauen ob ich evtl. etwas anders/besser machen kann/sollte?
Falls noch Probleme auftauchen melde ich mich hier wieder.

Gruß
euer Anfänger Wink
Private Nachricht senden Benutzer-Profile anzeigen
 
Anfänger 2.0
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 37
Anmeldedatum: 17.10.13
Wohnort: kreis Karlsruhe
Version: ---
     Beitrag Verfasst am: 17.09.2014, 15:09     Titel:
  Antworten mit Zitat      
Ok, ich habe einen Fehler...
und zwar funktioniert das Plotten im spmd nicht :/

Beziehungsweise plotte ich im Originalcode nur einmal zu Beginn und ändere später per
Code:
set(h, 'ydata', werte);
die Werte.

Irgendeine Idee wie ich das hinbiegen kann?

Wenn ich das jedesmal neu plotten will, kommt keine Errormeldung doch ein plot kommt auch nicht. Wenn ich es per set machen will, existiert das handle im Worker nicht.
Code:
Error detected on worker 2.
Invalid or deleted object.



Desweiteren wäre interessant wie ich Variablen und Handles in die Workspace der Worker importieren kann.
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: 17.09.2014, 20:03     Titel:
  Antworten mit Zitat      
Hallo,

das ist auch eine unrealistische Erwartung.
Dir muss klar sein, dass in dem parallel pool komplett unabhängige Prozesse laufen. Diese Prozesse sind so angelegt, dass sie sogar auf verschiedenen Rechnern laufen könnten. Das Plotten muss also entweder im Client stattfinden, oder du musst die generierten Figures abspeichern und dir die Dateien holen.

Zitat:
Desweiteren wäre interessant wie ich Variablen und Handles in die Workspace der Worker importieren kann.

Variablen: siehe mein letzter Beitrag.
Handles: ich würde sagen gar nicht, da die Grafikobjekte ja im anderen Prozess nicht existieren.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Anfänger 2.0
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 37
Anmeldedatum: 17.10.13
Wohnort: kreis Karlsruhe
Version: ---
     Beitrag Verfasst am: 18.09.2014, 10:41     Titel:
  Antworten mit Zitat      
Na dass die Prozesse unabhängig von einander laufen, ist mir ja schon klar.

Die Variablen unter den Workern gebe ich ja mit labSend/labReceive über.
Zeitlich macht die Übergabe nicht viel aus.
Ich wollte aber wissen, wie ich z.b. die variablen aus einer GUI handle übernehmen kann.

Ich dachte wenn ich aus einem Worker aus plotte hat das ja nichts mit dem anderen Worker zu tun.
Ich kann nicht mal plot(1,1) anwenden. Beziehungsweise wird es geplottet aber nicht visible? Ich weiß es nicht.
Wie kann ich das denn umgehen?.
Muss ich die Variablen unbedingt in eine Datei speichern und von dort wieder laden?


Es ist so, dass ich eine GUI mit axes und Buttons habe.
per Pushbutton wird die m-File zum plotten aufgerufen und die handles zu den Plots übergeben. Aus der m-File konnte ich dann Problemlos die Properties der handles bearbeiten. (bevor ich parallelisiert habe)

Also geht das jetzt nicht, da die Axes bzw. die gesamte Figure in den parallelen Prozessen garnicht existiert? Confused

Gruß
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: 18.09.2014, 19:09     Titel:
  Antworten mit Zitat      
Hallo,

was meinst du mit "die variablen aus einer GUI handle "?

Zitat:
Ich dachte wenn ich aus einem Worker aus plotte hat das ja nichts mit dem anderen Worker zu tun.
Ich kann nicht mal plot(1,1) anwenden. Beziehungsweise wird es geplottet aber nicht visible? Ich weiß es nicht.

Du siehst eben nur die Plots von deinem Prozess, aber nicht die der anderen Prozesse des parallel pools.

Zitat:
Also geht das jetzt nicht, da die Axes bzw. die gesamte Figure in den parallelen Prozessen garnicht existiert?

So würde ich es sehen, ja.

Siehe auch
http://www.mathworks.com/matlabcent.....reader/view_thread/286438

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Anfänger 2.0
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 37
Anmeldedatum: 17.10.13
Wohnort: kreis Karlsruhe
Version: ---
     Beitrag Verfasst am: 19.09.2014, 10:15     Titel:
  Antworten mit Zitat      
Hallo Harald,

danke für die Hilfe.

mit Variablen aus der GUI meinte ich:
in meinem Code habe ich variable Parameter die mit jedem Schleifendurchlauf aktualisiert werden.
Diese Variablen kann ich in der GUI setzen und während der Messung ändern.
In meinem Beispielcode hier wären das die Variablen 'a' 'b' und 'c'. Hier natürlich einfach random gesetzt.

Hmm verstehe. Die Frage wäre nun, ob man nun sagen könnte bspw.: ich will jetzt den Prozess mit labindex2 visible setzen.
Aber wie ich aus anderen Forenbeiträgen jetzt weiß ist pct ja nicht fähig zu plotten Sad

Ich habe jetzt übrigens einen anderen Lösungsweg gefunden:
Undzwar parfeval
Code:

function parfevalTest()
i = 1;
t = zeros(1,20000);
inc = zeros(1,20000);
ref = zeros(1,20000);
temp = zeros(1,20000);
value = 1.5;

PLOT = plot(NaN,NaN,NaN,NaN,NaN,NaN);

startTime = clock;

while i < 10
    tic
    %%%%%%%%%%%%%%%%%%%%
    NWAcheck = parfeval(@NWAmeasure,1,value);
    %%%%%%%%%%%%%%%%%%%%
   
    if i > 1
       
        Mat = round((rand(100,100).*100));
        pause(0.2);
        marker1 = round(rand(1)*100);
        marker2 = round(rand(1)*100);
       
        if marker1 == 0
            marker1 = marker1 + 1;
        end
        if marker2 == 0
            marker2 = marker2 + 1;
        end
       
        inc(i-1) = (Mat(marker1,marker2)+NWA(1))*10;
        ref(i-1) = (Mat(marker2,marker1)+NWA(1))*10;
       
        set(PLOT(1), 'xdata', t(1:i-1), 'ydata', temp(1:i-1));
        set(PLOT(2), 'xdata', t(1:i-1), 'ydata', inc(1:i-1));
        set(PLOT(3), 'xdata', t(1:i-1), 'ydata', ref(1:i-1));
       
    end
   
    temp(i) = round(rand(1)*100)+20;
    pause(0.1);
   
    a = rand(1);
    b = round(rand(1))+rand(1);
    c = rand(1)*2;
   
    if i ~= 1
        value = (temp(i)*a*b/2)+c;
    end
   

   
    t(i) = etime(clock,startTime);
    i = i + 1;
   
    %%%%%%%%%%%%%%%%%%%%
    NWA = fetchOutputs(NWAcheck);
    %%%%%%%%%%%%%%%%%%%%
    toc
end
end

function result = NWAmeasure(value)

result = rand(1,2).*value;
pause(0.5)

while result(2) < 0.5
    result = rand(1,2).*value;
    pause(0.5)
end

end
 

Natürlich habe ich parpool im voraus schon ausgeführt.

Die Methode klappt in meinem Beispiel zwar wunderbar, doch im Originalcode kommen die Messergebnisse ja nicht irgendwoher, sondern ich muss eine Verbindung zum Gerät erstellen mit NWA = nwaKlasse(ip).
Und wie wir ja schon wissen kann ich keine Objekthandles übergeben, da diese im Parallelpool nicht existiert. Confused Sad
Aus zeitlichen Gründen kann ich das Objekt nicht jedesmal im neuen Prozess neu erzeugen.

Fällt denn keinem eine Möglichkeit ein, wie man das machen kann..
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 - 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.