subplots - ¿Por qué no veo una aceleración significativa cuando uso el compilador MATLAB?
super title matlab (11)
Yo votaría por el perfil + luego veré cuáles son los cuellos de botella.
Si el cuello de botella es matemática matricial, probablemente no lo va a hacer mejor ... EXCEPTO una gran cantidad es la asignación de matriz. por ejemplo, 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 para preseleccionar la matriz (comenzar con ceros o NaN) y llenarlo desde allí:
s = zeros(50000,1);
for i = 1:50000
s(i) = 3;
end
Si el cuello de botella se repite las ejecuciones de una gran cantidad de llamadas a funciones, esa es una pregunta difícil.
Si el cuello de botella es algo que MATLAB no hace rápidamente (ciertos tipos de análisis sintáctico, XML, cosas así), entonces usaría Java, ya que MATLAB ya se ejecuta en una JVM y se conecta muy fácilmente con archivos JAR arbitrarios. Miré en la interfaz con C / C ++ y es REALMENTE feo. Microsoft COM está bien (solo en Windows) pero después de aprender Java no creo que vuelva a eso.
Tengo un montón de buen código de MATLAB que se ejecuta muy lentamente y sería un dolor de escribir en C. El compilador de MATLAB para C no parece ayudar mucho, en todo caso. ¿Debería acelerar la ejecución más? ¿Estoy jodido?
Como otros han notado, el lento código de Matlab a menudo es 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:
- Vea si hay bibliotecas / cajas de herramientas que puede usar. Estos generalmente se escribieron para ser muy optimizados.
- Haga un perfil de su código, encuentre los espacios reducidos y vuelva a escribirlos en C. simple. Conectar el código C (como archivos DLL, por ejemplo) a Matlab es fácil y está cubierto en la documentación.
En mi experiencia, el código lento de MATLAB generalmente proviene de no vectorizar tu código (es decir, escribir for-loops en lugar de solo multiplicar matrices (ejemplo simple)).
Si está haciendo E / S de archivo, tenga cuidado con la lectura de datos en una sola 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!
Me haré eco de lo que dijo dwj: si tu código MATLAB es lento, esto es probablemente porque no está lo suficientemente vectorizado. Si está haciendo bucles explícitos cuando podría estar haciendo operaciones en arreglos completos, ese es el culpable.
Esto se aplica igualmente a todos los lenguajes dinámicos orientados a matrices: Perl Data Language, Numeric Python, 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 usan código interno cuidadosamente codificado a mano bucles e instrucciones SIMD (por ejemplo, MMX, SSE, AltiVec).
Según el compilador de Matlab, probablemente se refiera al comando mcc, que acelera un poco el código eludiendo el intérprete de Matlab. Lo que aceleraría significativamente el código de MAtlab (por un factor de 50-200) es el uso del código C real compilado por el comando mex.
Si está utilizando el compilador de MATLAB (en una versión reciente de MATLAB), seguramente no verá ninguna aceleración. Esto se debe a que todo lo que el compilador realmente hace es darle una forma de empaquetar su código para que pueda ser distribuido a personas que no tienen MATLAB. No lo convierte en algo más rápido (como el código de máquina o C); simplemente lo envuelve en C para que pueda llamarlo.
Hace esto al hacer que su código se ejecute en el Tiempo de ejecución del compilador (MCR) de MATLAB, que es esencialmente el kernel computacional de MATLAB: su código aún se está interpretando. Gracias a la penalización que supone 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, podría decirse que el compilador en realidad no compila, al menos en el sentido tradicional de la palabra.
Las versiones anteriores del compilador funcionaban de manera diferente y las aceleraciones podían ocurrir en ciertas situaciones. Para la versión de Mathwork, ve a
http://www.mathworks.com/support/solutions/data/1-1ARNS.html
Primero, secundo todos los comentarios anteriores sobre el perfilado y la vectorización.
Para una perspectiva histórica ...
La versión anterior de Matlab permitía al usuario convertir m archivos a funciones mex preescribiendo el código m y convirtiéndolo en un conjunto de llamadas de biblioteca de matlab. Estas llamadas tienen todos los errores al verificar que el intérprete lo hizo, pero las versiones anteriores del intérprete y / o el analizador en línea eran lentas, por lo que la compilación del archivo m a veces ayuda. Por lo general, ayudó cuando tenía bucles porque Matlab fue 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 puede ver exactamente qué es obra.
En una versión más reciente (probablemente 2006a y posterior, pero no recuerdo), Mathworks comenzó a usar un compilador justo a tiempo para el intérprete. En efecto, este compilador JIT compila automáticamente todas las funciones mex, por lo que hacerlo explícitamente sin conexión no ayuda en absoluto. En cada versión desde entonces, también han puesto mucho esfuerzo en hacer que el intérprete sea mucho más rápido. Creo que las versiones más nuevas de Matlab ni siquiera te permiten compilar automáticamente archivos m en archivos mex porque ya no tienen sentido.
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 Perfilador). Además, el uso juicioso de "tic" y "toc" puede ayudar. No optimice su código hasta que sepa a dónde va el tiempo (no intente adivinar).
Tenga en cuenta que en matlab:
- las operaciones a nivel de bit son realmente lentas
- la E / S de archivo es lenta
- los bucles son generalmente lentos, pero la vectorización es rápida (si no conoce la sintaxis del vector, aprenda)
- las operaciones centrales son realmente rápidas (por ejemplo, matriz multiplicada, fft)
- si crees que puedes hacer algo más rápido en C / Fortran / etc, puedes escribir un archivo MEX
- hay soluciones comerciales para convertir matlab en C (google "matlab to c") y funcionan
¿Has intentado perfilar tu código? No necesita vectorizar TODO su código, solo las funciones que dominan el tiempo de ejecución. El generador de perfiles de MATLAB le dará algunos consejos sobre dónde pasa más tiempo su código.
Hay muchas otras cosas que debería leer en la sección Sugerencias para mejorar el rendimiento en el manual de MathWorks.
Puede portar su código a "Embedded Matlab" y luego usar Realtime-Workshop para traducirlo a C.
Embedded Matlab es un subconjunto de Matlab. No es compatible con Cell-Arrays, Graphics, Marices of dynamic size o algunos modos de direccionamiento Matrix. Puede llevar un esfuerzo considerable realizar el acceso a Embedded Matlab.
Realtime-Workshop es el núcleo de Code Generation Products. Escupe C genérico, o puede optimizar para una gama de Plataformas integradas. Lo más interesante para usted es quizás el xPC-Target, que trata el hardware de propósito general como un objetivo integrado.
El compilador de MATLAB termina su código m y lo envía a un tiempo de ejecución de MATLAB. Entonces, el rendimiento que ve en MATLAB debe ser el rendimiento que ve con el compilador.
Por las otras respuestas, vectorizar su código es útil. Pero, el JIT de MATLAB es bastante bueno en estos días y muchas cosas funcionan más o menos vectorizadas o no. Eso no quiere decir que no se obtengan beneficios de rendimiento de la vectorización, simplemente no es la bala mágica que alguna vez fue. La única forma de saber realmente es usar el generador de perfiles para averiguar dónde está viendo su código los cuellos de botella. Muchas veces hay algunos lugares donde puedes hacer refactorizaciones locales para mejorar realmente el rendimiento de tu código.
Hay un par de otros enfoques de hardware que puede tomar en el rendimiento. En primer lugar, gran parte del subsistema de álgebra lineal es multiproceso. Es posible que desee asegurarse de haber habilitado eso en sus preferencias si está trabajando en una plataforma multi-core o multiprocesador. En segundo lugar, es posible que pueda utilizar la caja de herramientas de computación en paralelo para aprovechar más los procesadores múltiples. 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.