Beschleunigte Matlab-C ++ - Konvertierung

8

Ich habe Matlab-Bildverarbeitungscode, der ziemlich langsam läuft und ich bin bereit, ihn in C / C ++ umzuwandeln. Ich weiß nicht wirklich viel darüber, wie Matlab funktioniert und wie Code ausgeführt wird, aber ich bin nur daran interessiert, welche Art von Beschleunigung ich erwarten könnte. Natürlich gibt es viele Variablen, die das beeinflussen werden, aber ich suche nur nach einem Leitfaden, vielleicht aus deinen eigenen Erfahrungen.

Danke

Zenna

    
zenna 04.08.2009, 21:41
quelle

7 Antworten

8

Es hängt hauptsächlich von der Dichte Ihrer Schleifen in Matlab ab. Wenn Sie nur eine Reihe von integrierten Matlab-Bildverarbeitungsfunktionen aufrufen, werden Sie höchstwahrscheinlich nicht in der Lage sein, die Leistung zu verbessern (höchstwahrscheinlich werden Sie es verletzen). Wenn Sie Bildpixel durchlaufen oder eine Art Blockverarbeitung durchführen, werden möglicherweise große Verbesserungen angezeigt. Wenn Sie eine Schleife ausführen, aber die Verarbeitungsmenge in jeder Iteration beträchtlich ist, sehen Sie möglicherweise nur eine geringe oder gar keine Verbesserung.

Ich sehe Matlab so, dass jede Zeile einen gewissen Overhead hat. Wenn Sie Ihre Lösung in die Form einer Matrix-Multiplikation oder einer anderen Vektor / Matrix-Operation bringen können, erleiden Sie diesen Overhead nur einmal und sind vernachlässigbar. Mit Loops erleiden Sie jedoch diesen Overhead jedes Mal, wenn die Schleife iteriert. Außerdem machen die meisten Bildbearbeitungsfunktionen von Matlab nur Aufrufe an optimierte Bibliotheken. Versuchen Sie also nicht, sie neu zu erstellen, wenn Sie nicht genau wissen, wo sie verbessert werden können.

Ich fand, dass der beste Ansatz eine Kombination aus C und Matlab ist. Ich benutze Matlab, wenn die Operation leicht vektorisiert werden kann (ausgedrückt in Vektor / Matrix-Operationen). Dies kann bedeuten, dass die Lösung aus einem anderen Blickwinkel kommt, als es am einfachsten scheint. Außerdem ist es schwer, Matlabs Plotten und Visualisieren zu übertreffen, so dass ich definitiv nicht zu einer C / C ++ - Komplettlösung wechseln würde, wenn Sie nicht planen, mit C / C ++ zu arbeiten (wenn das Teil Ihres Projekts ist).

>

Wenn ich keine relativ einfache Möglichkeit zur Vektorisierung finde, implementiere ich nur den Teil der Verarbeitung, der enge Schleifen in einer C-mex-Funktion benötigt, die von Matlab aufgerufen werden kann. Ich tendiere dazu, in diesem Fall C anstelle von C ++ zu verwenden, da der Prozess relativ klein sein sollte und nicht viel komplizierte Datenabstraktion benötigt, aber auch C ++ würde gut funktionieren. Stellen Sie sicher, dass Sie auf die Bilddaten in der Reihenfolge der Spalten zugreifen, um die Cache-Treffer zu maximieren, da Matlab so seine Matrizen organisiert.

    
Jason B 05.08.2009, 15:33
quelle
4

Es hängt wirklich von der Qualität Ihres Matlab-Codes ab und was Sie tun. Idiomatischer Matlab-Code, der von einem Matlab-Experten geschrieben wurde, wird schwer zu schlagen sein, besonders wenn Sie kein Optimierungsguru sind und aufgrund des Sprachwechsels nur eine Beschleunigung erwarten. Zum Beispiel fand ich, dass sogar einige der bekannteren C-basierten FFT-Bibliotheken der Matlab-FFT nicht gewachsen waren.

Wenn man ein schlecht geschriebenes Matlab-Programm mit einem durchschnittlich geschriebenen c ++ vergleicht, würde ich sagen, dass Sie nach meiner Erfahrung eine Größenordnung sehen.

    
maxaposteriori 04.08.2009 21:49
quelle
3

Die kurze Antwort auf die Frage, welche Art von Beschleunigung Sie bekommen können, ist "es kommt darauf an".

Matlab ist ein Interpreter, also ist es insgesamt viel langsamer als nativer C ++ - Code. Viele Matlab-Funktionen sind jedoch gut optimiert, und neuere Versionen enthalten JIT. Sie müssten also entscheiden, ob Sie Ihren gesamten Matlab-Code in C umschreiben, nur die kritischen Teile neu schreiben oder den Matlab-Code selbst optimieren, damit er schneller läuft.

Ich würde vorschlagen, dass Sie mit den in Matlab integrierten Profiling-Tools beginnen, um die Leistungsengpässe in Ihrer Anwendung zu finden. Es kann der Fall sein, dass Sie den Matlab-Code optimieren können, um eine bessere Leistung zu erzielen. Die Faustregel besteht darin, Schleifen zu vermeiden, indem vektorisierte Array-Operationen verwendet werden, anstatt jeweils ein Element zu durchlaufen.

    
Dima 04.08.2009 21:55
quelle
1

Zum Beispiel verwendet matlab die FFTW-Bibliothek, um fft-Algorithmen zu implementieren. Die Leistung dieser Bibliothek ist fast unmöglich zu schlagen. Die einzige, die ich kenne, die vergleichbar ist, ist die Intel Math Kernel Library (MKL), ist aber kommerziell. Zuerst würde ich vorschlagen, jede mathematische Bibliothek zu benutzen, die Sie finden können. Matlab macht das hinter den Kulissen.

Es ist wahr, dass es manchmal schwierig ist, Matlab zu schlagen. Aber die Sache ist, dass der Matlab-Profiler Ihnen nicht immer genug Informationen darüber gibt, wie Sie Ihren Code verbessern können. Sie wissen, dass einige Matlab-Methoden die meiste Zeit beanspruchen, aber Sie wissen nicht immer, ob es Möglichkeiten gibt, die Leistung zu verbessern, indem Sie sie auf andere Weise aufrufen, weil diese Methode eine Black-Box ist.

In C / C ++ gibt es Werkzeuge wie valgirnd , mit denen Sie prüfen können, ob der Assembler, den der Compiler erzeugt, Ihnen helfen kann der Compiler, um diesen Code zu verbessern, indem er beispielsweise eine Methode einreiht. Aber wieder verwendet Matlab professionelle mathematische Bibliotheken hinter den Kulissen und wenn die meiste Zeit für diese Bibliotheken aufgewendet wird, wenn Sie Ihren Matlab-Code ausführen, ist die Leistung schwer zu verbessern.

Ich würde dir einen anderen Ansatz geben. Sie können die Engpässe mit Matlab Profiler analysieren und sehen, ob es sich lohnt, diesen Code in nativen Code zu verschieben. Matlab erlaubt dir das. Sie können es auch anders herum tun. Sie können etwas in C / C ++ implementieren und Matlab für einige Operationen aufrufen, in denen Sie erfahren haben, dass Ihr nativer Code langsamer als Matlab ist.

    
javier-sanz 04.08.2009 22:21
quelle
1

Für die Bildverarbeitung können Sie eine spürbare Beschleunigung erzielen. Aber das hängt wirklich davon ab, wie gut Sie MATLAB-Code schreiben. Viele Dinge lassen sich vektorisieren oder durch eingebaute Funktionen pflegen. Diese Art von Code ist blitzschnell.

Wenn Sie jedoch feststellen, dass Ihr Code aus vielen Loops besteht (z. B. Schleifen über alle Pixel in einem Bild), wird er unglaublich langsam und die Vektorisierung kann 100x oder mehr beschleunigen.

Wenn Ihr Code in MATLAB sehr schwer "richtig" zu tun ist, kann der Wechsel zu C eine praktikable Option sein. Ich habe ein Computervisionsprojekt in der Schule (3D-Punkt-Rekonstruktion) gemacht, das dies deutlich gezeigt hat. Als unser Projekt, das in C ++ und OpenCV implementiert wurde, beendet war, hatte eines der anderen Gruppenprojekte die Bilder noch kaum geladen. Sie wurden in MATLAB geschrieben. Wir haben es nie zeitlich festgelegt, aber meine Vermutung ist, dass unsere Version ungefähr 10 mal schneller lief.

Aber andererseits war ihr MATLAB-Code wahrscheinlich überhaupt nicht optimiert. Es ist also nicht wirklich nützlich als Benchmark.

    
Hannes Ovrén 05.08.2009 11:05
quelle
1

Ich habe eine Matlab-Routine in C ++ exportiert und mit Visual Studio C ++ als Mex kompiliert. Die Beschleunigung war ein Faktor von 10. und wenn ich Multi-Kerne verwenden würde, hätte ich wahrscheinlich auch 3 mal mehr Geschwindigkeit.

Wenn Sie Pisten in Hanglagen haben und etwas mit den einzelnen Komponenten der Matrix machen, so etwas wie y (m, n) = x (m) * a - x (m-1) und das für Steigungen dann werden Sie eine gute Geschwindigkeit haben.

Wenn Sie viele Matlab-Funktionen zur Berechnung verwenden, wobei die Matlab-Funktion selbst viele Operationen ausführt, dann ist es weniger sinnvoll, Code in C ++ zu exportieren.

    
Jochen G. 07.08.2009 13:36
quelle
0

Wie andere bereits gesagt haben, verwenden Sie den MATLAB-Profiler, um die Engpässe zu erkennen. Wenn es Matrix-Zahlen-Knirschen ist, hast du einen ziemlich hohen Balken, um über MATLAB zu springen. Wenn Sie viele bedingte Anweisungen oder Funktionsaufrufe haben, können Sie Ihre Geschwindigkeit wahrscheinlich verbessern.

Stellen Sie sicher, dass Sie versuchen, die Anzahl der Datenübertragungen zwischen MATLAB und C ++ zu minimieren. Wenn Sie große Datenfelder in einem großen Cluster senden, ist es wahrscheinlich schnell. Andernfalls, wenn Sie viele Datenübertragungen durchführen, auch wenn Ihr C ++ - Programm schnell ist, verlieren Sie möglicherweise den Geschwindigkeitsvorteil bei der Datenkonvertierung.

Ich würde mir auch Ihre Algorithmen ansehen und überlegen, Java zu verwenden. Es ist sehr praktisch, benutzerdefinierten Java-Code von MATLAB aufzurufen, da MATLAB bereits auf einer JRE ausgeführt wird. Ich war sehr beeindruckt von der Geschwindigkeit der Übertragung großer Datenfelder zwischen MATLAB-Funktionen und meinem benutzerdefinierten Java-Code. Ich hatte vor ein paar Jahren einen Algorithmus in C ++ (mit MEX oder was auch immer) implementiert, um MATLAB zu beschleunigen, und es sah einfach wie ein Alptraum aus, mit allen Datenstrukturen umzugehen. Am Ende habe ich stattdessen COM / ActiveX benutzt, weil ich auf einem Windows-Rechner lief und die Verbindung viel einfacher war.

Nachdem ich eine Menge Low-Level-Programmierung zur Lösung numerischer Probleme gemacht habe, habe ich ein besseres Verständnis dafür, was schief gehen kann, von der numerischen Genauigkeit bis zur Programmierung von Wartungsproblemen. Wenn es keinen großen Leistungsvorteil gäbe, würde ich wählen eine höhere Sprache jeden Tag über C / C ++.

    
Jason S 05.08.2009 21:26
quelle