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

Code schlanker/schneller machen - Minimalbeispiel

 

Vaati
Forum-Anfänger

Forum-Anfänger


Beiträge: 21
Anmeldedatum: 12.02.17
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 17.10.2018, 17:41     Titel: Code schlanker/schneller machen - Minimalbeispiel
  Antworten mit Zitat      
Hallo liebes Forum,

ich bräuchte eure Hilfe in Sachen "Performance Steigern" für einen Codeabschnitt. Der Codeabschnitt befindet sich in einer while-schleife die per callback Funktion immer mal wieder verlassen wird, um den Vektor
Code:
neu "zu füllen".
Der Vektor Data hat die Struktur, dass alle 9 Werte der Wert 555 kommt, quasi wie ein Protokoll. Werte die davor auftauchen so wie nach der letzten 555 sollen abgeschnitten werden. Dann soll der Vektor zusätzlich auf die Länge eines Vielfachen von 8 gebracht werden. Daraus werden dann komplexe Werte extrahiert und es folgt eine Berechnung der FFT.
Habe meinen Codeabschnitt mal zu einem Minimalbeispiel zusammengefasst, sodass ihr damit arbeiten könnt.
Code:

clear all
load('minimal.mat','data')
Pad = 1; % ZeroPaddingFaktor
L = 512;
k=1;
N = 2^(nextpow2(L)+Pad);

% Werte mit Protokoll extrahieren
for proto=1:1:size(data,2)
    if data(1,proto) == 555
        data(1:proto) = [];
        break
    end
end
data = data(data~=555); %Protokollwert 555 löschen
data = data(1:(floor(size(data,2)/8))*8); %Vektor auf Länge 8 bringen

% Signal extrahieren
for pk = 1:1:8
    for l = pk:8:size(data,2)
        s(pk,k) = data(1,l);
        k=k+1;
    end
    k=1;
end
window = hann(size(s,2)) + 1i * hann(size(s,2));

% FFT Berechnen
for l=1:1:4
    Y = fft(((s((2*l)-1,:) + s((2*l),:) .* 1i)-mean((s((2*l)-1,:) + s((2*l),:) .* 1i))).*window',N).*(N/L); % FFT der komplexen Daten berechnen
    FFT(l,:) = 20*log10(abs(Y(1:(floor(N/2)+1)))); % Leistungsspektrum berechnen
end
 

Im Anhang ist der Vektor 'data'.

Ich freue mich über euren Input zur PerformanceSteigerung...bei Nachfragen immer her damit.

Liebe Grüße
Vaati

minimal.mat
 Beschreibung:

Download
 Dateiname:  minimal.mat
 Dateigröße:  17.23 KB
 Heruntergeladen:  207 mal
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: 18.10.2018, 11:48     Titel: Re: Code schlanker/schneller machen - Minimalbeispiel
  Antworten mit Zitat      
Hallo Vaati,

Bevor man versucht die Performance zu steigern, ist der Profiler nützlich: Zunächst findet man den Teil des Codes, der am meisten Rechenzeit benötigt, denn wenn man einen Teil doppelt so schnell macht, der nur 2% der gesamten Rechnenzeit verwendet, ist das Gesamt-Programm nur 1% schneller.

Zitat:
Der Codeabschnitt befindet sich in einer while-schleife die per callback Funktion immer mal wieder verlassen wird, um den Vektor
Code:
neu "zu füllen".

Wo wird der Code mit welchem Callback "verlassen"?

Das clear all ist auf jeden Fall ein dramatische Performance-Fresser. Damit entfernt man alle geladenen Funktionen aus dem RAM und die M-Files müssen zeitraubend wieder von der festplatte eingelesen werden. Ich verstehe nicht, wieso so viele Programmieranfänger diesen Befehl am Anfang ihrer Scripte verwenden, anstatt Funktionen zu verwenden. Ich vermute, viele Dozenten haben diese Unsitte noch von ihren Dozenten übernommen.

Das nächstre Problem ist load ohne die Outputs in einer Variable zu speichern. Dies erzeugt dynamisch Variablen im Workspace, und Matlabs JIT-Acceleration kann diese nicht effizient bearbeiten. Viel besser wäre also:
Code:
FileData = load('minimal.mat','data');
data = FileData.data;


Code:
L = 512;
N = 2^(nextpow2(L)+Pad);

nextpow2(512) ist eine Konstante. Das kann man dann auch gleich hard-codieren.

Code:
for proto=1:1:size(data,2)
    if data(1,proto) == 555
        data(1:proto) = [];
        break
    end
end

Besser:
Code:
index = find(data == 555, 1);
data = data(index+1:end);


Ich vermute:
Code:
for pk = 1:1:8
    for l = pk:8:size(data,2)
        s(pk,k) = data(1,l);
        k=k+1;
    end
    k=1;
end

kann so vereinfacht werden:
Code:
s = reshape(data, 8, []).';


Code:
   Y = fft(((s((2*l)-1,:) + s((2*l),:) .* 1i)-mean((s((2*l)-1,:) + s((2*l),:) .* 1i))).*window',N).*(N/L);

Hier wird s((2*l)-1,:) + s((2*l),:) .* 1i zwei mal berechnet, oder? Dann also besser in einer temporären Variablen speichern.
Wahrscheinlich benötigt aber FFT die meiste Zeit und diese Tipps helfen nur marginal. FFT kann man auf eine ganze Matrix anwenden, was effizienter wäre als für jeden einzelnen Vektor.

Gruß, Jan
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.