2009-08-04 12 views
8

Ho un codice di elaborazione delle immagini Matlab che gira abbastanza lentamente e sono pronto a convertirlo in C/C++. Non so davvero molto su come MATLAB funziona e su come il codice viene eseguito, ma sono solo interessato a sapere che tipo di accelerazioni potrei aspettarmi. Chiaramente ci sono molte variabili che influenzeranno questo, ma sto solo cercando una guida forse dalle tue esperienze.Speedup Conversione da Matlab a C++

Grazie

Zenna

+8

Ummm ... alcuni esempi di codice sarebbero belli. Non puoi prendere un algoritmo lento e schifoso in Matlab e aspettarti una conversione per renderlo veloce. Potresti non combattere l'interprete, potrebbe essere l'algoritmo –

risposta

8

Principalmente dipende dalla tenuta dei loop in Matlab. Se chiami semplicemente una serie di funzioni di elaborazione di immagini Matlab incorporate, molto probabilmente non sarai in grado di migliorare le prestazioni (molto probabilmente ti farai male). Se esegui il looping dei pixel dell'immagine o esegui una sorta di elaborazione dei blocchi, potresti notare notevoli miglioramenti. Se stai facendo un po 'di loop, ma la quantità di elaborazione all'interno di ogni iterazione è sostanziale, potresti vedere solo un miglioramento minimo o nullo.

Il modo in cui guardo Matlab è che ogni linea eseguita ha una certa quantità di spese generali. Se si può mettere la soluzione sotto forma di moltiplicazione di una matrice, o qualche altra operazione vettoriale/a matrice, si risente solo una volta di un sovraccarico ed è trascurabile. Tuttavia, con i loop, si soffre di quel sovraccarico ogni volta che il ciclo itera. Inoltre, la maggior parte delle funzioni di elaborazione delle immagini di Matlab sta solo effettuando chiamate verso librerie ottimizzate, quindi non provare a ricrearle a meno che non si sappia con certezza dove possono essere migliorate.

Ho trovato che l'approccio migliore è utilizzare una combinazione di C e Matlab. Io uso Matlab quando l'operazione può essere facilmente vettorizzata (messa in termini di operazioni vettore/matrice). Questo potrebbe voler dire arrivare alla soluzione da una prospettiva diversa da quella che sembra la più semplice. Inoltre, è difficile battere il plotting e la visualizzazione di Matlab, quindi non mi trasferirei a una soluzione C/C++ a meno che non si disponga di un piano per la visualizzazione con C/C++ (se questo è parte del progetto).

Se non riesco a trovare un modo relativamente semplice per vettorializzare, implego solo la parte di elaborazione che richiede cicli stretti in una funzione C mex che può essere chiamata da Matlab. In questo caso tendo ad usare C anziché C++ poiché il processo dovrebbe essere relativamente piccolo e non richiedere una grande quantità di astrazione dati complicata, ma il C++ funzionerebbe bene. Assicurati di accedere ai dati dell'immagine nell'ordine delle colonne per massimizzare gli hit della cache poiché questo è il modo in cui Matlab organizza le sue matrici.

+2

Con l'introduzione dell'acceleratore JIT, la "penalità del ciclo for" non è molto preoccupante come in passato. Usa il profiler per trovare i veri colli di bottiglia. – MatlabDoug

+1

Sì, sicuramente andrò per prima cosa, ma ho ancora trovato situazioni in cui C con ottimizzazioni può essere migliore, ma potrebbe essere solo la mia conoscenza limitata a trarre vantaggio dal compilatore JIT. Detto questo, evitando C/C++ dove Matlab può fare bene o meglio è una buona idea –

+0

@MatlabDoug: Potresti espandere l'acceleratore e il profiler JIT? Io faccio un sacco di programmazione MATLAB e non ne ho mai sentito parlare, ma sembrano interessanti. potresti fornire un paio di link? Grazie. – SSilk

4

E 'davvero dipende dalla qualità del codice Matlab e che cosa si sta facendo. Il codice Idiomatic Matlab scritto da un esperto di Matlab sarà difficile da battere, in particolare se non sei un guru dell'ottimizzazione e ti aspetti una accelerazione a causa del cambio di lingua. Per esempio, ho trovato che anche alcune delle più apprezzate librerie FFT basate su C non erano all'altezza della FFT di Matlab.

Detto questo, confrontando un programma Matlab scritto in modo scadente con un C++ scritto mediamente, direi che stai osservando un ordine di grandezza nella mia esperienza.

+3

Per FFT, Matlab usa FFTW ("la trasformata di Fourier più veloce in Occidente", vedi http://www.fftw.org), che è implementata in C (in realtà , Codice C generato da Objective Caml, vedi http://www.fftw.org/pldi99.pdf). – las3rjock

3

La breve risposta alla domanda su che tipo di accelerazioni si possono ottenere è "dipende".

Matlab è un interprete, quindi nel complesso è molto più lento del codice C++ nativo. Tuttavia, molte funzioni MATLAB sono ben ottimizzate e le versioni recenti includono JIT. Quindi dovresti decidere se riscrivere tutto il codice MATLAB in C, riscrivere solo le parti critiche o ottimizzare il codice MATLAB stesso per correre più velocemente.

Suggerisco di iniziare utilizzando gli strumenti di profilatura incorporati di Matlab per trovare i colli di bottiglia delle prestazioni nell'applicazione. Potrebbe essere il caso che tu possa modificare il codice MATLAB per ottenere prestazioni migliori. La regola empirica è di evitare i loop usando le operazioni di vettori vettorizzati invece di iterare un elemento alla volta.

+0

Con l'introduzione dell'acceleratore JIT, la "penalità del ciclo for" non è davvero preoccupante come in passato. Usa il profiler per trovare i veri colli di bottiglia. – MatlabDoug

1

Ad esempio, matlab utilizza la libreria FFTW per implementare gli algoritmi di fft. La performance di quella libreria è quasi impossibile da battere. L'unico che conosco è paragonabile all'intel Math Kernel Library (MKL), ma è commerciale. Quindi, prima di tutto, suggerirei di utilizzare tutti i libray matematici che riesci a trovare. Matlab lo sta facendo dietro le quinte.

È vero che a volte è difficile battere il matlab. Ma il fatto è che il profiler MATLAB non ti dà sempre abbastanza informazioni su come migliorare il tuo codice. Sapete che alcuni metodi MATLAB stanno prendendo la maggior parte del tempo, ma non sempre si sa se ci sono modi per migliorare le prestazioni chiamandoli in un altro modo perché questo metodo è una scatola nera.

In C/C++ si dispone di strumenti come valgirnd che consente di controllare anche se l'assemblatore che il compilatore sta generando e in questo modo è possibile aiutare il compilatore a migliorare il codice inserendo un metodo per esempio. Ma ancora una volta MATLAB sta usando le librerie matematiche professionali dietro le quinte e se la maggior parte del tempo è speso su quelle librerie quando si esegue il codice MATLAB, le prestazioni sono difficili da migliorare.

Vorrei provare un approccio diverso. Puoi analizzare i colli di bottiglia con matlab profiler e vedere se varrebbe la pena di spostare quel codice in codice nativo. Matlab ti permette quello. Puoi anche farlo al contrario. È possibile implementare un po 'di colla in C/C++ e chiamare matlab per alcune operazioni in cui si è verificato che il proprio codice nativo è più lento di quello matlab.

1

Per l'elaborazione delle immagini è possibile ottenere una notevole velocità. Ma questo dipende davvero da quanto sei bravo a scrivere il codice MATLAB. Un sacco di cose possono essere vettorializzate o essere curate da funzioni integrate. Quel tipo di codice è incredibilmente veloce.

Tuttavia, se si trova che il codice consta di molti loop (come ad esempio il loop su tutti i pixel di un'immagine) sarà incredibilmente lento e la vettorizzazione può dare un incremento di 100 volte o più.

Se il codice è molto difficile da eseguire "a destra" in MATLAB, passare a C può essere un'opzione valida. Ho fatto un progetto di computer vision a scuola (ricostruzione 3D dei punti) che ha mostrato chiaramente questo. Quando il nostro progetto, che è stato implementato in C++ e OpenCV, ha terminato il calcolo, uno dei progetti di altri gruppi non ha ancora caricato le immagini. I loro furono scritti in MATLAB. Non l'abbiamo mai programmato, ma il mio indovina è che la nostra versione ha funzionato circa 10 volte più velocemente.

Ma poi di nuovo, il loro codice MATLAB probabilmente non è stato ottimizzato affatto. Quindi non è davvero utile come punto di riferimento.

+0

Con l'introduzione dell'acceleratore JIT, la "penalità del ciclo for" non è davvero preoccupante come in passato. Usa il profiler per trovare i veri colli di bottiglia. – MatlabDoug

+0

Sì, l'ho sentito anche io. Purtroppo non ho ancora avuto il piacere di lavorare con le nuovissime versioni di MATLAB :( –

0

Come altri hanno già detto, utilizzare il profiler MATLAB per vedere quali sono i colli di bottiglia. Se si tratta di numeri matriciali, hai una barra piuttosto alta da saltare per battere MATLAB. Se hai un sacco di istruzioni condizionali o chiamate di funzione, è più probabile che tu possa migliorare la tua velocità.

Assicurati di provare a ridurre il numero di volte in cui i dati vengono trasferiti tra MATLAB e C++. Se si inviano matrici di dati di grandi dimensioni in un unico grande insieme, è probabile che sia veloce. Altrimenti, se esegui molti trasferimenti di dati avanti e indietro, anche se il tuo programma C++ è veloce, potresti perdere il vantaggio di velocità nella conversione dei dati.

Vorrei anche esaminare i vostri algoritmi e considerare l'utilizzo di Java. È molto comodo chiamare codice Java personalizzato da MATLAB, poiché MATLAB è già in esecuzione su un JRE. Sono rimasto molto impressionato dalla velocità di trasferimento di grandi matrici di dati tra le funzioni MATLAB e il mio codice Java personalizzato.Ho cercato di implementare un algoritmo in C++ puro (usando MEX o qualsiasi altra cosa) qualche anno fa per velocizzare MATLAB, e sembrava proprio un incubo trattare tutte le strutture di dati. Alla fine ho usato COM/ActiveX perché stavo girando su una macchina Windows e l'interfaccia era molto più semplice.

Dopo aver fatto un sacco di programmazione di basso livello per risolvere problemi numerici, ho un migliore apprezzamento per ciò che può andare storto, dall'accuratezza numerica ai problemi di manutenzione della programmazione e, a meno che non ci fosse un enorme vantaggio in termini di prestazioni, avrei scegliere un linguaggio di livello superiore ogni giorno su C/C++.

1

Esportare una routine MATLAB in C++ e compilare con Visual Studio C++ come mex. L'accelerazione era un fattore di 10. e se volessi usare multi-core, allora avrei anche una velocità 3 volte superiore.

Se hai pendenze in pendenza e fai qualcosa con i singoli componenti della matrice, qualcosa come y (m, n) = x (m) * a - x (m-1) e questo in per pendenze poi tu avrà una buona accelerazione.

se si utilizza molte funzioni MATLAB per il calcolo, in cui la stessa funzione MATLAB esegue molte operazioni, quindi ha meno senso esportare il codice in C++.