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

'eval' in 'parfor'-Schleife umgehen

 

nealz
Forum-Anfänger

Forum-Anfänger


Beiträge: 20
Anmeldedatum: 04.02.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 06.02.2015, 17:15     Titel: 'eval' in 'parfor'-Schleife umgehen
  Antworten mit Zitat      
Guten Tag zusammen,

in nachfolgendem Code habe ich aus einer for-Schleife eine parfor-Schleife gemacht, um meine Anwendung schneller zu machen. Dabei gab es schon so manchen Stolperstein, jetzt komme ich aber gerade nicht allein weiter.

Code:


parfor i_kampagnen=1:length(kampagnen)
.
.
.

x=load(filenames(i_files).name,'allg_fahrumgebung','allg_fahrstil');
        m=x.allg_fahrumgebung;
        n=x.allg_fahrstil;
        index_fahrumgebung=find(m==true);
        index_fahrstil=find(n==true);
        if isempty(index_fahrumgebung)
            index_fahrumgebung=5;
        end
        if isempty(index_fahrstil)
            index_fahrstil=4;
        end
            for i_signal=1:length(signalnames)
                for i_vars=1:length(varname)
                      load(filenames(i_files).name, varname{i_vars});%Nur selektierte Signale laden
                      signalnames_temp{i_signal,1}=varname{i_vars};
                        if ~exist(['allg_t' varname{i_vars}(end-1:end)],'var')
                            load(filenames(i_files).name,['allg_t' varname{i_vars}(end-1:end)]);
                            signalnames_temp{anz_sig,1}=['allg_t' varname{i_vars}(end-1:end)];
                            signal_temp(anz_sig,1)={eval(['allg_t' varname{i_vars}(end-1:end)])};
                            anz_sig=anz_sig-1;
                        end
                        %Cell-Array mit allen Signalen
                        signal_temp(i_signal,1)={eval(varname{i_vars})};
                        break                
                end
            end
end
.
.
.
clear(signalnames_temp{:})
        clear signal_temp
end

 



Ich möchte die beiden 'eval' umgehen, die noch im Code stehen.

Meine bisherige Forensuche bei GoMatlab war wenig erfolgreich.
Es gab einmal Vorschläge hinsichtlich cell2struct oder ähnlichem, um eval zu umgehen, aber ich habe aber noch keine Lösung gefunden.

Habt ihr vielleicht eine Idee oder eigene Erfahrungen gemacht?

Ich bin für jeden Hinweis dankbar! Wink
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


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

die evals resultieren wohl daraus, dass Informationen in den Variablennamen "versteckt" sind. Das ist keine gute Idee.
Genauso, wie du es zuvor schon gemacht hast, würde ich die Daten aus der .mat-Datei in eine Struktur laden. Dann ist die Indizierung einfacher:
Code:
y = load(...)
z = y.(name)


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

Forum-Anfänger

Forum-Anfänger


Beiträge: 20
Anmeldedatum: 04.02.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 09.02.2015, 17:53     Titel:
  Antworten mit Zitat      
Hallo Harald,

vielen Dank für die Antwort!

Wie bekomme ich denn die Info korrekt in signal_temp(anz_sig,1) hinein?
Da finde ich bisher keinen Weg..

Code:

.
.
.
q=load(filenames(i_files).name,['allg_t' varname{i_vars}(end-1:end)]);
r=q.(['allg_t' varname{i_vars}(end-1:end)]);
signalnames_temp{anz_sig,1}=['allg_t' varname{i_vars}(end-1:end)];
signal_temp(anz_sig,1)=r;
anz_sig=anz_sig-1;
.
.
.
 


Da bekomme ich für signal_temp(anz_sig,1)=r; den Fehler:
Subscripted assignment dimension mismatch.

signal_temp(anz_sig,1)=q.(['allg_t' varname{i_vars}(end-1:end)]);

würde ja m.M.n. auch Sinn machen, klappt aber auch nicht.
Was mache ich hier falsch?

Vielen Dank schonmal!
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


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

Zitat:
Wie bekomme ich denn die Info korrekt in signal_temp(anz_sig,1) hinein?

Welcher Art ist die Info denn? Wenn r ein Vektor oder eine Matrix ist, dann kannst du das nicht in ein Element einer Matrix schreiben.

Meine Empfehlung wäre, zunächst mal for statt parfor zu verwenden und dann mit dem Debugger zu arbeiten.

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

Forum-Anfänger

Forum-Anfänger


Beiträge: 20
Anmeldedatum: 04.02.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 09.02.2015, 20:29     Titel:
  Antworten mit Zitat      
Es ist ein Vektor...

Ich habe eine Version mit for, da läuft auch alles.
Dauert aber teilweise extrem lange, daher jetzt die Idee auf parfor umzustellen.

Sieht das ganze denn anders aus wenn ich mit parfor nur eine gewisse Funktion aufrufen würde, in der ich dann quasi alles mögliche abhandel?
Aber das birgt vermutlich neue Schwierigkeiten ...
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.499
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 09.02.2015, 21:00     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
Sieht das ganze denn anders aus wenn ich mit parfor nur eine gewisse Funktion aufrufen würde, in der ich dann quasi alles mögliche abhandel?

Ja, das hilft häufig.

Siehe auch
http://de.mathworks.com/videos/seri.....ting-tutorials-97719.html
(insbesondere Part 4)

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

Forum-Anfänger

Forum-Anfänger


Beiträge: 20
Anmeldedatum: 04.02.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 09.02.2015, 21:14     Titel:
  Antworten mit Zitat      
Vielen Dank, das wird morgen das erste sein was ich tue!

Freue mich sehr über die Hilfe!
Private Nachricht senden Benutzer-Profile anzeigen
 
nealz
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 20
Anmeldedatum: 04.02.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 11.02.2015, 17:14     Titel:
  Antworten mit Zitat      
Soo,

ich habe jetzt etwas rum gebastelt und die zeitintensiven Stellen in der Anwendung ausfindig gemacht.
Die eine ist eben jener Speichervorgang, den ich nun mithilfe von parfor schneller abhandeln will.

Hier mein Code Stand jetzt, und der funktioniert soweit auch:

Code:

.
.
parfor i_sichern=1:length(NAMES)
final=auswahl.(NAMES{i_sichern});
savefunc(final,i_sichern);
end

.
.

function savefunc(final,i_sichern)
zusatz=i_sichern;
save(['final' num2str(zusatz)], '-v7.3');
end

 


Das Problem: nun dauert es wesentlich (!) länger als vorher.
Das liegt wohl daran, dass ich eben nicht vor der PARFOR Schleife den Input "slice", wie MATLAB es ausdrückt, sonder dass "auswahl" immer komplett an jeden einzelnen Worker übergeben wird.

Bist du auch der Meinung, dass dies das Problem ist, oder siehst du noch ein weiteres?

Ich möchte mit der PARFOR Schleife "auswahl" komplett abspeichern, aber nach Fahrzeugen getrennt, genau so wie es jetzt auch passiert.

Weißt du wie ich es schaffe, dass PARFOR jedem Worker von vornherein nur "seinen slice" übergibt, um dann diesen gesondert abzuspeichern?

Dazu sei gesagt, dass die Anzahl an "slices" variabel ist, je nachdem wieviele Fahrzeuge es gibt!


Bin für jeden Hinweis dankbar Smile
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.499
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 11.02.2015, 21:07     Titel:
  Antworten mit Zitat      
Hallo,

eine Möglichkeit dürfte sein, die Struktur in ein Cell Array umzuwandeln und in dieses zu indizieren.
Läuft der Code lokal auf einem Rechner? Dann sehe ich das Hauptproblem woanders: das Hauptproblem ist ja nicht die Rechenarbeit, sondern das Schreiben von Dateien. Du magst mehrere Kerne beschäftigen, hast ja aber immer noch "nur" eine Festplatte, und auf die wollen nun mehrere Prozesse gleichzeitig zugreifen.
Es wäre bei sowas immer hilfreich, wenn man ein reproduzierbares Beispiel (gerne mit Phantasiedaten, aber die Dimensionen der Daten sollten in vergleichbaren Größenordnungen sein) hätte.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 12.02.2015, 17:56     Titel:
  Antworten mit Zitat      
Hallo nealz,

Haralds Kommentar trifft den Punkt: Hier ist wahrscheinlich die Festplatte der begrenzende Faktor und mehrere Kerne gleichzeitig per SAVE speichern zu lassen wird das Problem wahrscheinlich eher vergrößern, denn dann muss der Schreib-Lese-Kopf ja noch öfter hin und her springen.

Was bei SAVE LAufzeit bringen kann ist die Kompression abzuschalten, indem man z.B. das v6-Format wählt. Lies mal unter "doc save" nach.

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
nealz
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 20
Anmeldedatum: 04.02.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.02.2015, 18:07     Titel:
  Antworten mit Zitat      
Hallo Harald,

zuerst einmal vielen Dank für die Antworten. Das ist eine schöne Sache.

Ich habe die besagte Structure nun in ein cell array umgewandelt und als solches versucht mit parfor abzuspeichern.
Das ändert aber soweit erstmal nichts. Also habe ich das entweder nicht so gemacht, wie du es meintest oder aber das Problem liegt halt, wie von dir angeführt, am Schreiben der Dateien.

Was kann man da denn machen?

Mit ist heute zudem aufgefallen, dass die Performance der Anwendung [z.B. in MB/s] scheinbar direkt abhängig von der Größe der zu speichernden Daten im Workspace ist.
Bei kleinerer zu speichernder Datenmenge (~1 GB) läuft die Anwendung sehr flüssig und man denkt, man hat die Lösung gefunden. Da funktioniert alles genau wie ich das möchte. Aber sobald die Speichermenge eine kritische Grenze erreicht (irgendwo oberhalb einem Gigabyte) stellt MATLAB fast die Arbeit ein. Der gesamte Desktop ist phasenweise eingefroren, der Task Manager zeit allerdings die meiste Zeit lediglich eine CPU-Auslastung von 1% an. Der Arbeitsspeicher (16 GB vorhanden) hingegen ist durchweg gut bis sehr gut ausgelastet.

Nun habe ich - wie im unten angehängten Code - vor dem Speichern der Daten alle größeren, nicht mehr gebrauchten Dateien aus dem workspace entfernt. Leider ändert das nichts.

Beispiel:
Ich speichere Dateien für zwei Fahrzeuge ab, wobei der eine "Datenwürfel" am Ende ~700 MB groß ist, der andere lediglich <100 MB.
Insgesamt also <1 GB. Das geht ruck zuck.

Wenn ich nun noch einmal zwei Fahrzeuge wähle, jenes mit 700 MB und ein weiteres von dem ich weiß dass es ähnlich groß ist, dauert allein die erste Speicherschleife um ein vielfaches länger als vorher, obwohl der Output (der ersten Schleife) genauso groß ist.

Daher müssen die Einbuße in der Performance meiner Meinung nach irgendwie auch schon von der "insgesamt beabsichtigten Menge" der zu speichernden Daten abhängen.


Kurz zu meiner Anwendung:

Es wird mithilfe MetaDaten eine GUI aufgebaut, in der der Nutzer nach diversen Kriterien aus einem Stamm von Daten eine Selektion vornehmen kann. Der für mich interessante Teil beginnt nun, wenn der Nutzer "Datenwürfel erzeugen" klickt und MATLAb die Info der vorgenommenen Selektion erhält:..............

Code:

GUI=guihandles(h.Fig);
%Ausgewählte Signale und Fahrzeuge an Würfelfunktion suchen und übergeben
c=1;
selected_channels=get(GUI.listbox_channels_selected,'String');
selected_fzgnames_string=get(GUI.listbox_fzgnames,'String');
selected_fzgnames_value=get(GUI.listbox_fzgnames,'Value');
for i_fzgnames=1:length(selected_fzgnames_string)
    if i_fzgnames == selected_fzgnames_value(c)
        selected_fzgnames{c,1}=selected_fzgnames_string{i_fzgnames,1};
        if length(selected_fzgnames_value)==c
            break
        else
            c=c+1;
        end
    end
end
set(GUI.static_fehler,'String','Passende Daten werden gesucht...');
Figobj=findobj('-property','Enable');
set(Figobj,'Enable','off');
%Infos über Fahrstil und Fahrumgebung suchen und übergeben
fahrumgebung=[get(GUI.checkbox_fahrumgebung_stadt,'Value'),get(GUI.checkbox_fahrumgebung_land,'Value'),get(GUI.checkbox_fahrumgebung_autobahn,'Value'),get(GUI.checkbox_fahrumgebung_berg,'Value')];
fahrstil=[get(GUI.checkbox_fahrstil_schonend,'Value'),get(GUI.checkbox_fahrstil_durchschnitt,'Value'),get(GUI.checkbox_fahrstil_sport,'Value')];

[wuerfel]=datenwuerfel(selected_channels,selected_fzgnames,fahrumgebung,fahrstil,h);

for anz_kamp=1:length(selected_fzgnames)
    %Kampagnennamen aus Fahrzeugnamen extrahieren
    unterstrich=strfind(selected_fzgnames{anz_kamp,1},'_');
    kampagnenname{anz_kamp,1}=selected_fzgnames{anz_kamp,1}(unterstrich(end-1)+1:unterstrich(end)-1);
end
   
for i_kampagnen=1:length(selected_fzgnames)
    NAMES = fieldnames(wuerfel.(['Kampagne_' kampagnenname{i_kampagnen}]));
     auswahl.(NAMES{i_kampagnen})=wuerfel.(['Kampagne_' kampagnenname{i_kampagnen}]).(NAMES{i_kampagnen});
end

clear wuerfel;
clear h;
clear Figobj;
clear GUI;

for i_NAMES=1:length(NAMES)
    final=struct2cell(auswahl.(NAMES{i_NAMES}));
    %dateien=fieldnames(final{i_NAMES});
    anz_dateien=length(final);
    parfor i_sichern=1:anz_dateien
    wuerfelchen=final{i_sichern};
    savefunc(wuerfelchen,i_sichern,i_NAMES,NAMES);
    end
end


function savefunc(wuerfelchen,i_sichern,i_NAMES,NAMES)
dirpath=pwd;
zusatz=i_sichern;
if ~exist([dirpath '\Datenwuerfel\' NAMES{i_NAMES,1}])
    mkdir([dirpath '\Datenwuerfel\'], NAMES{i_NAMES,1});
    addpath([dirpath '\Datenwuerfel\' NAMES{i_NAMES,1}]);
end
save([dirpath '\Datenwuerfel\' NAMES{i_NAMES,1} '\wuerfelchen' num2str(zusatz) '.mat'],'wuerfelchen','-v7.3');
end

 


[wuerfel] = datenwuerfel lädt dabei die passenden Dateien in den Workspace und ruft dazu wiederum eine weitere Funktion auf.
Das ist sehr umfangreich, daher hoffe ich dass der Codeausschnitt reicht.

Wo brauche ich nun konkret Antworten:

-habe ich die Umstellung von structure zu cell array so gemacht, wie du es meintest?

-Warum ist meine CPU-Auslastung während der parfor-Schleife fast die gesamte Zeit bei ~1%?

-Macht es Sinn, vor der parfor Schleife gewisse Teile des Workspace zu "clearen"?

-Wie habe ich diese Unterschiede hinsichtlich der Performance zu verstehen? Bei kleinen Dateien geht es fix, bei (mehreren) größeren Dateien geht die Anwendung in die Knie. (Das gilt übrigens auch für die funktionierende Version mit for statt parfor. Auch hier nimmt die Performance spürbar ab, jedoch erst bei einem Gesamtoutput ~2,5 GB)


Besten Dank & schönen Abend noch!
Private Nachricht senden Benutzer-Profile anzeigen
 
nealz
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 20
Anmeldedatum: 04.02.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.02.2015, 18:08     Titel:
  Antworten mit Zitat      
Oh hallo Jan,

vielen Dank für deine Antwort, da haben wir gerade gleichzeitig geschrieben.

Werde ich gleich mal machen!
Danke!
Private Nachricht senden Benutzer-Profile anzeigen
 
nealz
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 20
Anmeldedatum: 04.02.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.02.2015, 18:42     Titel:
  Antworten mit Zitat      
Das ist jetzt lediglich eine Wasserstandsmeldung, aber scheinbar verbessert diese Umstellung die Performance deutlich!

Ich werde das jetzt mal über Nacht an größeren Daten testen, denn dort wird es erst wirklich interessant.

Der (selbe) Output ist nun allerdings um ein vielfaches Größer, das ist vermutlich ein Umstand, mit dem man dann Leben muss, nehme ich an?

Aber da werde ich morgen noch ein wenig rumprobieren und dann berichten.

Fürs erste - vielen Dank!
Private Nachricht senden Benutzer-Profile anzeigen
 
nealz
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 20
Anmeldedatum: 04.02.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 14.02.2015, 11:21     Titel:
  Antworten mit Zitat      
Hallo,

leider hilt die Umstellung auf v6 auch nur bei verhältnismäßig kleinen Datenwürfeln (komprimiert <1 GB).

Offensichtlich kann Matlab kleinere Datenpakete sehr viel besser handhaben (in MB/s) als größere. Zeitmessungen haben bei mir ergeben, dass die Geschwindkeit ab einer gewissen Datengrößer deutlich einbricht.

Nun frage ich mich: Kann man so etwas wie einen "Datenbegrenzer" oder "Datenbremse" einbauen? Also dass die Anwendung bei einer bestimtmen Größe an eingelesenen Daten das Einlesen weiterer Daten vorerst stoppt, mit dem eingelesenen Datenpaket weiterarbeitet und wenn er damit fertig ist, sich das nächste Paket lädt?

In meiner Anwendung gehe ich jetzt bereits einen Schritt in diese Richtung in dem ich nun gar keinen Datenwürfel mehr erzeuge, sondern ich speichere die nach bestimmten Kriterien ausgewählten und dann eingelesenen Daten direkt separat wieder ab. Gesondert nach Fahrzeugen.

Das Problem: Der Nutzer kann neben einigen anderen Kriterien nach Fahrzeugen und nach Signalen eine Auswahl treffen. Da ich nun separat nach Fahrzeugen abspeichere, läuft die Anwendung auch bei sehr großen Datenwürfeln (~10 GB) ziemlich flüssig, solange die vorgenommenen Auswahl zwar viele Fahrzeuge, aber jeweils nur einige wenige Signale betrifft.
Andersrum geht Matlab bei nur einigen wenigen Fahrzeugen und dafür vielen Signalen wieder in die Knie.

Meine Fragen:

-gibt es so etwas wie einen "Datenbegrenzer" oder ein Erkennen von Dateigrößen in matlab, dass hierbei hilfreich sein könnte um die Datenpakete klein zu halten?

-Macht es vielleicht Sinn, insgesamt eher nach Signalen zu speichern als Fahrzeuge, oder dreht das das Problem nur um?


Danke!
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


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

kommen die Daten denn wirklich aus MATLAB oder eventuell aus Simulink?

Insbesondere bei kommerziellen Anwendungen würde ich da auch mal direkt MathWorks kontaktieren.

Grüße,
Harald
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.