Domanda

Ho un bel codice MATLAB che gira troppo lentamente e sarebbe un problema scrivere in C. Il compilatore MATLAB per C non sembra aiutare molto, se non del tutto. Dovrebbe accelerare di più l'esecuzione? Sono fregato?

È stato utile?

Soluzione

Farò eco a ciò che ha detto DWG: se il tuo codice MATLAB è lento, probabilmente è perché non è sufficientemente vettorializzato. Se stai eseguendo cicli espliciti quando potresti eseguire operazioni su interi array, questo è il colpevole.

Questo vale anche per tutti i linguaggi dinamici orientati all'array: Perl Data Language, Numeric Python, MATLAB / Octave, ecc. È anche vero in una certa misura nel codice compilato C e FORTRAN compilato: le librerie di vettorializzazione appositamente progettate generalmente usano attentamente la mano loop interni codificati e istruzioni SIMD (ad es. MMX, SSE, AltiVec).

Altri suggerimenti

Se stai utilizzando il compositore MATLAB (su una versione recente di MATLAB) quasi sicuramente non vedremo alcun aumento di velocità. Questo perché tutto il compilatore in realtà ti dà un modo per impacchettare il tuo codice in modo che possa essere distribuito a persone che non hanno MATLAB. Non lo converte in qualcosa di più veloce (come codice macchina o C) - lo avvolge semplicemente in C in modo da poterlo chiamare.

Lo fa facendo eseguire il tuo codice sul MATLAB Compiler Runtime (MCR) che è essenzialmente il kernel computazionale MATLAB - il tuo codice viene ancora interpretato. Grazie alla penalità sostenuta per aver invocato l'MCR potresti scoprire che il codice compilato viene eseguito più lentamente rispetto a quando lo esegui semplicemente su MATLAB.

In altre parole, potresti dire che il compilatore non si sta effettivamente compilando, almeno nel senso tradizionale della parola.

Le versioni precedenti del compilatore funzionavano in modo diverso e in determinate situazioni potevano verificarsi accelerazioni. Per l'approccio di Mathwork vai a

http://www.mathworks.com/support/solutions/ dati / 1-1ARNS.html

Nella mia esperienza, il lento codice MATLAB di solito deriva dal non vettorializzare il tuo codice (ovvero scrivere for-loop anziché semplicemente moltiplicare le matrici (esempio semplice)).

Se stai eseguendo l'I / O su file, cerca i dati in un pezzo alla volta. Cerca nei file della guida la versione vettoriale di fscanf.

Non dimenticare che MATLAB include anche un profiler!

In primo luogo, secondo i commenti di cui sopra sulla profilazione e la vettorizzazione.

Per una prospettiva storica ...

La versione precedente di Matlab consentiva all'utente di convertire i file m in funzioni mex pre-analizzando il codice m e convertendolo in una serie di chiamate alla libreria matlab. Queste chiamate hanno tutti gli errori che controllano l'interprete, ma le vecchie versioni dell'interprete e / o del parser online erano lente, quindi la compilazione del file m a volte sarebbe di aiuto. Di solito ti è stato d'aiuto quando hai avuto dei loop perché Matlab era abbastanza intelligente da incorporare un po 'di quello in C. Se hai una di quelle versioni di Matlab, puoi provare a dire allo script mex di salvare il file .c e puoi vedere esattamente di cosa si tratta facendo.

Nella versione più recente (probabilmente 2006a e successive, ma non ricordo), Mathworks ha iniziato a utilizzare un compilatore just-in-time per l'interprete. In effetti, questo compilatore JIT compila automaticamente tutte le funzioni di mex, quindi farlo esplicitamente offline non aiuta affatto. Da allora in ogni versione hanno anche fatto molti sforzi per rendere l'interprete molto più veloce. Credo che le versioni più recenti di Matlab non ti permettano nemmeno di compilare automaticamente file m in file mex perché non ha più senso.

Il compilatore MATLAB racchiude il tuo codice m e lo invia a un runtime MATLAB. Quindi, le prestazioni che vedi in MATLAB dovrebbero essere le prestazioni che vedi con il compilatore.

Per le altre risposte, è utile vettorializzare il codice. Ma MATLAB JIT è abbastanza buono in questi giorni e molte cose si comportano in modo approssimativo o vettorializzato o meno. Questo non vuol dire che non ci sono benefici prestazionali da ottenere dalla vettorializzazione, non è il proiettile magico che era una volta. L'unico modo per dirlo davvero è usare il profiler per scoprire dove il tuo codice sta riscontrando colli di bottiglia. Spesso ci sono alcuni posti in cui è possibile eseguire il refactoring locale per migliorare davvero le prestazioni del codice.

Ci sono un paio di altri approcci hardware che puoi adottare per le prestazioni. Innanzitutto, gran parte del sottosistema di algebra lineare è multithread. Potresti voler assicurarti di averlo abilitato nelle tue preferenze se stai lavorando su una piattaforma multi-core o multi-processore. In secondo luogo, potresti essere in grado di utilizzare la casella degli strumenti di calcolo parallelo per sfruttare maggiormente i processori multipli. Infine, se sei un utente Simulink, potresti essere in grado di utilizzare emlmex per compilare m-code in c. Ciò è particolarmente efficace per i lavori a virgola fissa.

Hai provato a profilare il tuo codice? Non è necessario vettorializzare TUTTO il codice, ma solo le funzioni che dominano il tempo di esecuzione. Il profiler MATLAB ti darà alcuni consigli su dove il tuo codice sta trascorrendo più tempo.

Ci sono molte altre cose che dovresti leggere su Suggerimenti per migliorare le prestazioni nel manuale di MathWorks.

mcc non accelera affatto il tuo codice - non è proprio un compilatore.

Prima di arrenderti, devi eseguire il profiler e capire dove sta andando tutto il tuo tempo (Strumenti- > Open Profiler). Inoltre, l'uso giudizioso di " tic " e "toc" può aiutare. Non ottimizzare il codice finché non sai dove sta andando il tempo (non provare a indovinare).

Tieni presente che in matlab:

  • le operazioni a livello di bit sono molto lente
  • L'I / O del file è lento
  • i cicli sono generalmente lenti, ma vettorializzare è veloce (se non si conosce la sintassi vettoriale, impararla)
  • le operazioni principali sono molto veloci (ad es. moltiplicazione matrice, fft)
  • se pensi di poter fare qualcosa più velocemente in C / Fortran / etc, puoi scrivere un file MEX
  • ci sono soluzioni commerciali per convertire matlab in C (google "matlab in c") e funzionano

Puoi trasferire il tuo codice su " Embedded Matlab " e quindi utilizza Realtime-Workshop per tradurlo in C.

Matlab incorporato è un sottoinsieme di Matlab. Non supporta array di celle, grafica, marices di dimensioni dinamiche o alcune modalità di indirizzamento Matrix. Potrebbe essere necessario uno sforzo considerevole per eseguire il port su Embedded Matlab.

Realtime-Workshop è al centro dei prodotti di generazione del codice. Sputa C generico o può ottimizzare per una vasta gamma di piattaforme integrate. Il più interessante per te è forse xPC-Target, che tratta l'hardware per scopi generici come target incorporato.

Vorrei votare per la profilazione + quindi guardare quali sono i colli di bottiglia.

Se il collo di bottiglia è matematica, probabilmente non hai intenzione di fare di meglio ... TRANNE un grande gotcha è l'allocazione di array. per esempio. se hai un ciclo:

s = [];
for i = 1:50000
  s(i) = 3;
end

Questo deve continuare a ridimensionare l'array; è molto più veloce preselezionare l'array (inizia con zeri o NaN) & amp; riempilo da lì:

s = zeros(50000,1);
for i = 1:50000
  s(i) = 3;
end

Se il collo di bottiglia viene ripetuto esecuzioni di molte chiamate di funzioni, è difficile.

Se il collo di bottiglia è roba che MATLAB non fa rapidamente (alcuni tipi di analisi, XML, roba del genere) allora userei Java poiché MATLAB è già in esecuzione su una JVM e si interfaccia facilmente con file JAR arbitrari. Ho guardato l'interfaccia con C / C ++ ed è DAVVERO brutto. Microsoft COM è ok (solo su Windows) ma dopo aver appreso Java non penso che ci tornerò mai più.

Come altri hanno notato, il lento codice Matlab è spesso il risultato di un'insufficiente vettorializzazione.

Tuttavia, a volte anche il codice perfettamente vettoriale è lento. Quindi, hai diverse altre opzioni:

  1. Verifica se ci sono librerie / toolbox che puoi usare. Di solito venivano scritti per essere molto ottimizzati.
  2. Crea il profilo del tuo codice, trova i punti stretti e riscrivi quelli in chiaro C. Connettere il codice C (come DLL per esempio) a Matlab è facile ed è trattato nella documentazione.

Per compilatore Matlab si intende probabilmente il comando mcc, che velocizza un po 'il codice aggirando l'interprete Matlab. Ciò che accelererebbe significativamente il codice MAtlab (di un fattore 50-200) è l'uso del codice C effettivo compilato dal comando mex.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top