Pregunta

Tengo un montón de código MATLAB agradable que se ejecuta muy lentamente y sería un problema escribirlo en C. El compilador de MATLAB para C no parece ayudar mucho, en todo caso. ¿Debería estar acelerando más la ejecución? ¿Estoy jodido?

¿Fue útil?

Solución

Me haré eco de lo que dijo dwj: si su código MATLAB es lento, probablemente sea porque no está suficientemente vectorizado. Si estás haciendo bucles explícitos cuando podrías estar haciendo operaciones en arreglos completos, ese es el culpable.

Esto se aplica por igual a todos los lenguajes dinámicos orientados a matrices: lenguaje de datos Perl, Python numérico, MATLAB / Octave, etc. Incluso es cierto hasta cierto punto en el código compilado C y FORTRAN compilado: las bibliotecas de vectorización especialmente diseñadas generalmente se usan cuidadosamente Codificaciones internas e instrucciones SIMD codificadas (por ejemplo, MMX, SSE, AltiVec).

Otros consejos

Si está utilizando el compatible con MATLAB (en una versión reciente de MATLAB), entonces Es casi seguro que no verá ninguna aceleración en absoluto. Esto se debe a que todo lo que realmente hace el compilador es darle una forma de empaquetar su código para que se pueda distribuir a las personas que no tienen MATLAB. No lo convierte a nada más rápido (como el código de máquina o C), simplemente lo envuelve en C para que pueda llamarlo.

Hace esto haciendo que su código se ejecute en MATLAB Compiler Runtime (MCR), que es esencialmente el núcleo computacional de MATLAB; su código aún se está interpretando. Gracias a la penalización en que se incurre al tener que invocar el MCR, es posible que el código compilado se ejecute más lentamente que si simplemente lo ejecutara en MATLAB.

Dicho de otra manera, se podría decir que el compilador en realidad no se compila, al menos en el sentido tradicional de la palabra.

Las versiones anteriores del compilador funcionaban de manera diferente y las aceleraciones podrían ocurrir en ciertas situaciones. Para la versión de Mathwork sobre esto, vaya a

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

En mi experiencia, el código MATLAB lento generalmente viene de no vectorizar su código (es decir, escribir bucles for en lugar de simplemente multiplicar matrices (ejemplo simple)).

Si está realizando la E / S de archivos, busque datos de lectura de una pieza a la vez. Busque en los archivos de ayuda la versión vectorizada de fscanf.

¡No olvide que MATLAB también incluye un generador de perfiles!

Primero, segundo los comentarios anteriores sobre perfilado y vectorización.

Para una perspectiva histórica ...

La versión más antigua de Matlab permitía al usuario convertir m archivos a las funciones de mex haciendo un análisis previo del código m y convirtiéndolo en un conjunto de llamadas de la biblioteca matlab. Estas llamadas tienen todas las comprobaciones de errores que tuvo el intérprete, pero las versiones anteriores del intérprete y / o el analizador en línea eran lentas, por lo que compilar el archivo m a veces ayudaría. Por lo general, fue útil cuando tenía bucles porque Matlab era lo suficientemente inteligente como para incluir algo de eso en C. Si tiene una de esas versiones de Matlab, puede intentar decirle al script mex que guarde el archivo .c y podrá ver exactamente qué es. obra.

En la versión más reciente (probablemente 2006a y posterior, pero no lo recuerdo), Mathworks comenzó a usar un compilador justo para el intérprete. En efecto, este compilador JIT compila automáticamente todas las funciones mex, por lo que hacerlo de forma explícita sin conexión no ayuda en absoluto. Desde entonces, en cada versión, también se han esforzado para que el intérprete sea mucho más rápido. Creo que las versiones más recientes de Matlab ni siquiera te permiten compilar automáticamente archivos m en archivos mex porque ya no tiene sentido.

El compilador de MATLAB envuelve su código m y lo envía a un tiempo de ejecución de MATLAB. Por lo tanto, el rendimiento que se ve en MATLAB debe ser el que se ve con el compilador.

Para las otras respuestas, vectorizar tu código es útil. Pero, el MATLAB JIT es bastante bueno en estos días y muchas de las cosas funcionan de manera generalizada o bien vectorizadas. Eso no quiere decir que no se obtengan beneficios de rendimiento de la vectorización, simplemente no es la bala mágica que una vez fue. La única forma de saber realmente es usar el generador de perfiles para averiguar dónde está su código viendo cuellos de botella. Muchas veces hay algunos lugares donde puedes hacer refactorización local para mejorar realmente el rendimiento de tu código.

Hay un par de otros enfoques de hardware que puede asumir en el rendimiento. En primer lugar, gran parte del subsistema de álgebra lineal es multiproceso. Es posible que desee asegurarse de haberlo habilitado en sus preferencias si está trabajando en una plataforma de varios núcleos o varios procesadores. En segundo lugar, es posible que pueda utilizar la caja de herramientas de computación paralela para aprovechar más los múltiples procesadores. Finalmente, si usted es un usuario de Simulink, puede usar emlmex para compilar m-code en c. Esto es particularmente efectivo para el trabajo de punto fijo.

¿Has probado perfilar tu código? No es necesario que vectorice TODO su código, solo las funciones que dominan el tiempo de ejecución. El perfilador de MATLAB le dará algunos consejos sobre dónde está gastando más tiempo su código.

Hay muchas otras cosas que debes leer en Consejos para mejorar el rendimiento en el manual de MathWorks.

mcc no acelerará tu código en absoluto, no es realmente un compilador.

Antes de darse por vencido, debe ejecutar el generador de perfiles y averiguar a dónde va todo su tiempo (Herramientas- > Abrir perfil). Además, el uso juicioso de " tic " y " toc " poder ayudar. No optimice su código hasta que sepa dónde va el tiempo (no intente adivinar).

Ten en cuenta que en matlab:

  • las operaciones de nivel de bits son realmente lentas
  • el archivo I / O es lento
  • los bucles son generalmente lentos, pero la vectorización es rápida (si no conoce la sintaxis vectorial, apréndala)
  • las operaciones principales son realmente rápidas (por ejemplo, la multiplicación de matriz, fft)
  • si cree que puede hacer algo más rápido en C / Fortran / etc, puede escribir un archivo MEX
  • hay soluciones comerciales para convertir matlab a C (google " matlab a c ") y funcionan

Usted podría portar su código a " Embedded Matlab " y luego use Realtime-Workshop para traducirlo a C.

Embedded Matlab es un subconjunto de Matlab. No es compatible con matrices de celdas, gráficos, marices de tamaño dinámico o algunos modos de direccionamiento de matriz. Es posible que se requiera un esfuerzo considerable para migrar a Embedded Matlab

Realtime-Workshop es el núcleo de los productos de generación de código. Escupe una C genérica, o puede optimizarse para una gama de plataformas integradas. Quizás lo más interesante para usted sea el xPC-Target, que trata el hardware de propósito general como un objetivo incrustado.

Votaría por el perfil + luego vería cuáles son los cuellos de botella.

Si el cuello de botella es una matriz matemática, probablemente no lo harás mejor ... EXCEPTO un gran problema es la asignación de matrices. p.ej. Si tienes un bucle:

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

Esto tiene que seguir cambiando el tamaño de la matriz; es mucho más rápido preseleccionar la matriz (comience con ceros o NaN) & amp; rellénalo desde allí:

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

Si el cuello de botella es la ejecución repetida de muchas llamadas a funciones, es difícil.

Si el cuello de botella es algo que MATLAB no hace rápidamente (ciertos tipos de análisis, XML, cosas así) entonces usaría Java ya que MATLAB ya se ejecuta en una JVM y se interconecta muy fácilmente con archivos JAR arbitrarios. Miré a la interfaz con C / C ++ y es REALMENTE feo. Microsoft COM está bien (solo en Windows) pero después de aprender Java, creo que nunca volveré a eso.

Como han dicho otros, el código lento de Matlab es a menudo el resultado de una vectorización insuficiente.

Sin embargo, a veces incluso el código perfectamente vectorizado es lento. Entonces, tienes varias opciones más:

  1. Vea si hay alguna biblioteca / caja de herramientas que pueda usar. Estos usualmente fueron escritos para ser muy optimizados.
  2. Cree un perfil de su código, encuentre los lugares estrechos y reescriba los que están en la letra C simple. Conectar el código C (como DLL, por ejemplo) a Matlab es fácil y está cubierto en la documentación.

Por compilador de Matlab probablemente te refieres al comando mcc, que acelera un poco el código al eludir el intérprete de Matlab. Lo que aceleraría significativamente el código MAtlab (por un factor de 50-200) es el uso del código C real compilado por el comando mex.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top