Ich muss ein Stück MATLAB Code optimieren. Der Code ist einfach, aber er ist Teil einer Berechnungseinheit, die ihn ~ 8000 mal aufruft (ohne Redundanz) (Diese Berechnungseinheit wird in realen Fällen ~ 10-20K mal verwendet). Der gesamte MATLAB-Code ist ziemlich lang und komplex (für einen Physiker, wie ich), aber MATLAB Profiler behauptet, dass das folgende Segment für fast die Hälfte der Laufzeit (!) Verantwortlich ist.MATLAB Matrix Element weise Multiplikationsoptimierung
Der Code multipliziert grundsätzlich elementar jede Permutation von 3 Matrizen aus 3 Gruppen (A, B, C) und summiert sie mit einer gewissen Gewichtung. Gruppe A hat eine einzige Matrix, Gruppe B hat 4 Matrizen und Gruppe C hat 7.
Ich habe versucht, einige Vektorisierungstechniken * noch bestenfalls die gleiche Laufzeit zu bekommen.
Mit dem MATLAB Profiler habe ich die Gesamtzeit überprüft, die für jede Zeile aufgewendet wurde (für alle 8000 Aufrufe) - ich habe diese in Kommentare geschrieben.
for idx_b = 1:4
B_MAT=B_Container_Cell{idx_b};
for idx_c = 1:7
C_MAT = C_Container_Cell{idx_b}(:,:,idx_c); % 60 sec
ACB=A_MAT.*C_MAT.*B_MAT; % 20 sec
Coeff_x = Coeff_x_Cell{idx_b}(p1,p2,idx_c,p3);
Coeff_y = Coeff_y_Cell{idx_b}(p1,p2,idx_c,p3);
Coeff_z = Coeff_z_Cell{idx_b}(p1,p2,idx_c,p3);
Sum_x = Sum_x+Coeff_x.*ACB; % 15 sec
Sum_y = Sum_y+Coeff_y.*ACB; % 15 sec
Sum_z = Sum_z+Coeff_z.*ACB; % 15 sec
end
Ende
Vorkenntnissen -
A_MAT ist 1024x1024 komplexe Doppel konstante Matrix ouside der Schleife
B_MAT definiert ist 1024x1024 Doppelmatrix, im wesentlichen sparse (nur 0 und 1-Werte, sind solche, ~ 5 % von gesamt-Elemente)
C_MAT ist 1024x1024 komplexe Doppel
Sum_x/Sum_y/Sum_z richtig
initiiert wurden Coeff_X/Coeff_y/Coeff_z sind Doppelskalare
p1, p2, p3 sind Parameter (Konstante für dieses Codesegment)
Weiß jemand, warum die aufwendigste Operation ist variable Zuweisung? (Ich habe versucht, die Zuordnung zu überspringen und ersetzen C_MAT direkt mit seinem Ausdruck, aber es verschlechtert die Leistung)
Vektorisierung Versuch
Die techique I versuchte Katze zu verwenden, neu zu gestalten und repmat 3 zu erstellen Riese 2D-Matrizen, multipliziere diese elementweise und lege dann alles (mit Umformen) übereinander und summiere über die relevante Dimension. Die erste Matrix war A wiederholt 4 · 7 = 28 mal, die zweite war die 4 B-Matrizen, die 7 mal wiederholt wurden und die dritte war alle C-Matrizen überspannt (= 28 Matrizen).
Probeneingang
der Code auf den folgenden link erzeugen Probeneingabedateien. Die Laufzeit mit diesen Variablen (auf meinem Computer) ist ~ 0,38 sec (der ursprüngliche Code + Variablen ~ 0,42, der Unterschied ist meiner Meinung nach, weil der echte C-Cell-Container sehr groß ist, so dauert die Extraktion mehr Zeit)
'*' Betrieb kommutativ (im Gegensatz zu '*' Matrix multiplizieren), so dass man 'A_MAT * B_MAT' außerhalb der inneren Schleife durchführen kann. –
@BenVoigt ändert sich nicht viel die Leistung. – Alexander
Sie verweisen auf Vektorisierungstechniken in Ihrer Frage, was haben Sie versucht? – BillBokeey