Verfasst am: 27.10.2013, 14:16
Titel: Vektorisierung einer Matrixbefüllung
Hallo,
für ein Programm mit dem ein Roboter später Hindernisse umfahren soll benötige ich an einem Punkt statt einer For-Schleife eine Vektorisierung und erhoffe mir davon eine bessere Performance.
Es geht darum, dass eine 3D-Matrix auf jeder Ebene ein 2D-Bild erhält, wobei der Index der Ebene angibt wie weit das auf ihr liegende Bild über circshift verschoben ist. Es gilt, die folgende Schleife zu vektorisieren:
Verfasst am: 27.10.2013, 17:17
Titel: Re: Vektorisierung einer Matrixbefüllung
Hallo Pixel,
Statt der Vektorisierung würde ich zunächst eine Kopie des Codes von CIRCSHIFT in Deine Schleife einfügen und dabei das Parsen der Inputs und das Error-Handling weglassen. Wenn Du das dann noch vereinfachst (die 0 in [0, i] kann man ja getrost ignorieren), sollte das schon sehr effizeint sein.
danke für die Antwort. Könntest du mir vielleicht ein Beispiel zeigen, da ich als Matlab-Anfänger mit den Begriffen nichts anzufangen weiß.
Die Schleife muss am Ende nicht nur 40, sondern auch 200 mal für ein Bild durchlaufen, das dauert im Moment auch mal 2-10 Sekunden, im Idealfall hätte ich das natürlich gern deutlich schneller (<100-200ms).
Gibt es keine Möglichkeit, dem 3D-Array mit einem Befehl wie 'data(:,:,v)=...' in einer Zeile für jedes Element de Vektors die entsprechenden Werte zuzuweisen?
Die Pre-allocation macht hier schon mal einen großen Unterschied, da nicht in jeder Iteration ein neues Array erstellt werden und die bisherigen daten kopiert werden müssen.
Damit komme ich bei einem 1000x1000 Array schon von 7.7 of 0.6 Sekdungen, wenn CIRCSHIFT benutzt wird. Mit dem inlined Code oben, der alles macht, was CIRCSHIFT auch macht, lassen sich kaum Verbesserungen erzielen, da der Overhead von CIRSHIFT hier vernachlässigbar ist.
Deutlich schneller wird das aber, wenn nicht die Input-Matrix immer wieder geshiftet wird, sondern der Index im zu erstellenden Output-Array:
Code:
n = 40;
data = zeros([size(bild), n]); % Pre-allocation!!!
s2 = size(bild, 2);
for k = 1:n
data(:, mod(k:s2-1+k, s2) + 1, k) = bild;
end
Die Vektorisierung würde huier nicht viel bringen, da dann das Erstellen der großen Index-Matrix viel Zeit beanspruchen würde.
Allerdings ist das Erstellen eines großen Arrays mit nahezu redundanter Information im Allgemeinen eine schlechte Strategie. Wozu soll das Array künstlich aufgeblasen werden? Wäre es nicht geschickter, das "on-the-fly" zu machen, wenn die geshifteten Untermatritzen verwendet werden?
Gruß, Jan
Pixel_
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 28.10.2013, 01:04
Titel:
Guten Abend,
wieder einmal vielen Dank für die Antwort. Innerhalb der Schleife soll im Programm nicht allein das geshiftete Bild, sondern der Betrag der Differenzen des geshifteten und eines weiteren Bildes gespeichert werden. Ich nahm Anfangs an, dass die Matrixgröße dabei keinen signifikanten Performanceeinfluss hat, doch damit lag ich wohl falsch. Auch wenn ich die Subtraktion mit dem Befehl 'imabsdiff' gegenüber einer manuellen Variante verbessern konnte, so beansprucht das Programm bei der vollen Bildauflösung von 1280*800p und 100 Verschiebungen knapp 5 Sekunden, was definitiv zu lang ist.
Momentan sieht das ganze so aus, wobei data_l und data_r die beiden verschiedenen Bilder sind:
Oh, das Einfügen von IMABSDIFF ist eine andere Geschichte. Bitte poste solch wichtige Details unbedingt gleich am Anfang.
Da man IMABSDIFF für DOUBLEs laut des Hilfe-Textes mit ABS(A-B) ersetzen kann, würde ich das mal probieren. Es wundert mich aber immer noch, dass dieses Programm 5 Sekunden braucht.
Ich kann auch nicht mehr nachvollziehen, welche Geschwindigkeits-Gewinne meine Vorschläge bewirken. Das macht es schwierig, weitere Vorschläge zu machen.
Bitte verwende den Profiler um das Bottleneck zu finden.
Gruß, Jan
Einstellungen und Berechtigungen
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
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.