Compensación de rendimiento: ¿Cuándo es MATLAB mejor/más lento que C/C++?
performance (9)
Soy consciente de que C / C ++ es un lenguaje de nivel inferior y genera un código de máquina relativamente optimizado cuando lo comparamos con cualquier otro lenguaje de alto nivel. Pero creo que hay mucho más que eso, lo que también es evidente en la práctica.
Cuando hago cálculos simples como el promedio de Montecarlo de una colección de muestra Gaussiana, veo que no hay mucha diferencia entre una implementación de C ++ o la implementación de MATLAB, a veces, de hecho, MATLAB funciona un poco mejor en el tiempo.
Cuando paso a simulaciones de mayor escala con miles de líneas de código, lentamente aparece la imagen real. Las simulaciones C ++ muestran un rendimiento superior como 100 veces mejor en complejidad de tiempo que una implementación MATLAB equivalente.
El código en C ++ la mayoría de las veces es bastante serial y no se realiza una optimización de alta fidelidad explícitamente. Mientras que, según mi conocimiento, MATLAB hace mucha optimización de forma inherente. Esto aparece, por ejemplo, cuando trato de generar una gran cantidad de muestras aleatorias, mientras que el equivalente en C ++ que utiliza alguna biblioteca como IT ++ / GSL / Boost es relativamente más lento (el algoritmo utilizado es el mismo, a saber, mt19937).
Mi pregunta es simplemente saber si existe una compensación más simple entre MATLAB / C ++ en el rendimiento. ¿Es como lo que dice la gente, "Siempre que puedas, C / C ++ es mejor" (El experimentado con frecuencia) ?. En una perspectiva diferente, "¿Para qué sirve MATLAB, aparte de la comodidad?"
Por cierto, no veo que el parámetro de eficiencia de codificación sea significativo aquí, pensando en el mismo programador en ambos casos. Y también, creo que las otras alternativas como python, R no son relevantes aquí. Pero la dependencia de las bibliotecas específicas que utilizamos debería ser interesante.
[Soy un estudiante de doctorado en Coding Theory en sistemas de comunicación. Hago simulaciones usando matlab / C ++ todo el tiempo, y tengo experiencia razonable de codificar unos 10K de líneas en ambos casos]
Además de la velocidad del programa final, también debe tener en cuenta el tiempo total de desarrollo de su código, es decir, no solo el tiempo para escribir, sino también para depurar, etc. Matlab (y su contraparte de código abierto, Octave ) puede ser bueno para el prototipado rápido debido a su capacidad de visualización.
Si está utilizando C ++ directo (es decir, sin bibliotecas de matrices), puede tomarle mucho más tiempo escribir código C ++ que sea equivalente al código de Matlab (por ej., No tiene sentido gastar 10 horas escribiendo código C ++ que solo ejecuta 10 segundos más rápido, en comparación con un programa de Matlab que tardó 5 minutos en escribirse).
Sin embargo, existen bibliotecas de matriz de C ++ dedicadas, como Armadillo , que proporcionan una API similar a Matlab. Esto puede ser útil para escribir código de rendimiento crítico que se puede invocar desde Matlab o para convertir el código de Matlab en programas "reales".
Algunos códigos de Matlab usan ficciones de álgebra lineal estándar con multiproceso integrado. Entonces, parece que son más rápidos que un código C secuencial.
Como estudiante de doctorado también, y un usuario de 10 años de Matlab, me complace compartir mi punto de vista:
Matlab es una gran herramienta para el desarrollo y prototipos de algoritmos, especialmente cuando se trata de GUI, análisis de alto nivel (dominio de frecuencia, optimización de LS, etc.): codificación rápida, sintaxis potente (piense en [], {} ,: etc.).
Tan pronto como su cadena de procesamiento sea más estable y definida y las dimensiones de los datos crezcan, cambie a C / C ++.
El principal límite de Matlab aumenta cuando se considera que su lenguaje es similar a un script: siempre que evite cualquier ciclo (utilizando arrayfun, cellfun u otros procedimientos de matriz) las actuaciones son altas ya que la subrutina llamada vuelve a estar en C / C ++.
Creo que puedes considerar la diferencia en cuatro pliegues al menos.
- Compilado vs interpretado
- Fuertemente tipado vs tipado dinámicamente
- Rendimiento vs Prototipado rápido
- Fuerza especial
Para 1-3 se puede generalizar fácilmente en comparación entre dos familias de lenguajes de programación.
Para 4, MATLAB
está optimizado para operaciones de matriz. Entonces, si puedes vectorizar más código en MATLAB
, el rendimiento puede aumentar drásticamente. Por el contrario, si se requieren muchos loops
, no dude en utilizar C++
o crear un archivo mex
.
Es una pregunta difícil después de todo.
En mi experiencia (varios años de Visión artificial y procesamiento de imágenes en ambos idiomas) no hay una respuesta simple a esta pregunta, ya que el rendimiento de Matlab depende en gran medida (y mucho más que el rendimiento de C ++) de su estilo de codificación.
En general, Matlab envuelve las clásicas bibliotecas de álgebra lineal basadas en C ++ / Fortran. Entonces cualquier cosa como x = A/b
va a ser muy rápido. Además, Matlab hace un buen trabajo al elegir el solucionador más eficiente para este tipo de problemas, por lo que para x = A/b
Matlab observará el tamaño de sus matrices y elegirá las rutinas apropiadas de bajo nivel.
Matlab también brilla en la manipulación de datos de matrices grandes si "vectoriza" su código, es decir, si evita los bucles y utiliza matrices de índice o matrices booleanas para acceder a sus datos. Esto está altamente optimizado.
Para otras rutinas, algunas están escritas en el código Matlab, mientras que otras apuntan a una implementación C / C ++ (por ejemplo, las cosas de Delaunay). Puede verificar esto usted mismo escribiendo edit some_routine.m
. Esto abre el código y verá si es todo Matlab o simplemente un contenedor para algo compilado.
Matlab, creo, es principalmente para la comodidad, pero la comodidad se traduce en tiempo de codificación y, en última instancia, en dinero, por lo que Matlab se utiliza en la industria. Además, es fácil de aprender para ingenieros de otros campos además de la informática, con poca capacitación en programación.
He estado usando Matlab y C ++ durante aproximadamente 10 años. Para cada algoritmo numérico implementado para mi investigación, siempre comienzo desde el prototipado con Matlab y luego traduzco el proyecto a C ++ para obtener una mejora en el rendimiento de 10x a 100x (no estoy bromeando). Por supuesto, estoy comparando el código optimizado de C ++ con el código de Matlab completamente vectorizado. En promedio, la mejora es de aproximadamente 50x.
Hay muchas sutilezas detrás de los dos lenguajes de programación, y los siguientes son algunos malentendidos:
Matlab es un lenguaje de script pero se compila C ++
Matlab utiliza el compilador JIT para traducir su secuencia de comandos a código de máquina, puede mejorar su velocidad a lo máximo en un factor de 1.5 a 2 mediante el uso del compilador que proporciona Matlab.
El código de Matlab puede ser completamente vectorizado pero debes optimizar tu código a mano en C ++
El código de Matlab completamente vectorizado puede invocar bibliotecas escritas en C ++ / C / Assembly (por ejemplo, Intel MKL). Pero el código simple de C ++ puede ser razonablemente vectorizado por los compiladores modernos.
Las cajas de herramientas y las rutinas que proporciona Matlab deben estar muy bien ajustadas y deben tener un rendimiento razonable
No. Aparte de las rutinas de álgebra lineal, el rendimiento generalmente es malo.
Las razones por las que puede obtener un rendimiento de 10x ~ 100x en C ++ en comparación con el código de Matlab vectorizado:
Llamar a bibliotecas externas (MKL) en Matlab cuesta tiempo.
La memoria en Matlab se asigna dinámicamente y se libera. Por ejemplo, multiplicación de matrices pequeñas:
A = B*C + D*E + F*G
requiere que Matlab cree 2 matrices temporales. Y en C ++, si asigna su memoria de antemano, crea NINGUNO. Y ahora imagina que bucle esa declaración por 1000 veces. Otra solución en C ++ es proporcionada por C ++ 11 Rvalue reference. Esta es una de las mayores mejoras en C ++, ahora el código C ++ puede ser tan rápido como el código C simple.Si desea hacer un procesamiento paralelo, el modelo de Matlab es multiproceso y el modo C ++ es de múltiples hilos. Si tiene muchas tareas pequeñas que necesitan ser paralelizadas, C ++ proporciona una ganancia lineal para muchos subprocesos, pero puede tener una ganancia de rendimiento negativa en Matlab.
Pasas objetos grandes, un trozo de memoria por referencia en C ++, pero es bastante complicado en Matlab.
La vectorización en C ++ implica el uso de intrínsecos / ensamblaje, y a veces la vectorización SIMD solo es posible en C ++.
Los punteros hacen maravillas en C ++. Imágenes intercambiando dos matrices A y B: en Matlab, implica una tercera matriz y requiere 3 * N * N operaciones de copia elementales. Pero en C ++, esto se hace mediante punteros con un costo cercano a cero.
En C ++, es posible que un programador experimentado evite por completo el error de caché L2 e incluso la falta de caché L1, lo que empuja a la CPU a su límite de rendimiento teórico. El rendimiento de Matlab puede retrasarse un 10% por detrás de C ++ debido solo a esta razón.
En C ++, las instrucciones intensivas computacionales a veces se pueden agrupar según sus latencias (código cuidadosamente en ensamblaje o intrínsecos) y dependencias (la mayoría de las veces se hace automáticamente mediante compilador o hardware de CPU), de forma que el IPC teórico (instrucciones por ciclo de reloj) pueda ser alcanzado y las tuberías de la CPU están llenas.
Sin embargo, el tiempo de desarrollo en C ++ también es un factor de 10x en comparación con Matlab.
Las razones por las que debe usar Matlab en lugar de C ++:
Visualización de datos. ¡Creo que mi carrera puede continuar sin C ++, pero no podré sobrevivir sin Matlab solo porque puede generar hermosas tramas!
Rutinas y cajas de herramientas de baja eficiencia pero matemáticamente robustas. Obtenga la respuesta correcta primero y luego hable de eficiencia. Las personas pueden cometer errores sutiles en C ++ (por ejemplo, convertir implícitamente de doble a int ) y obtener una especie de resultados correctos.
Exprese sus ideas y presente su código a sus colegas. El código de Matlab es mucho más fácil de leer y mucho más corto que C ++, y el código de Matlab se puede ejecutar correctamente sin compilador. Me niego a leer el código C ++ de otras personas. Ni siquiera uso las bibliotecas científicas C ++ GNU porque la calidad del código no está garantizada. Es peligroso para un investigador / ingeniero utilizar una biblioteca de C ++ como una caja negra y tomar la precisión que se le concede. Incluso para bibliotecas C / C ++ comerciales, recuerdo que el compilador de Intel tuvo un error de signo en su función sin () el año pasado y también se produjeron problemas de precisión numérica en MKL.
Por último pero no menos importante:
Debido a que una vez que el código de Matlab se vectoriza, no queda mucho para que un programador optimice, el rendimiento del código de Matlab es mucho menos sensible a la calidad del código en comparación con el código de C ++. Por lo tanto, es mejor optimizar los algoritmos de cálculo en Matlab, y los algoritmos marginalmente mejores normalmente tienen un rendimiento marginalmente mejor en Matlab. Por otro lado, la prueba de algoritmo en C ++ requiere un programador decente para escribir algoritmos optimizados más o menos de la misma manera, y para asegurarse de que el compilador no optimice los algoritmos de manera diferente.
Matlab hace muy bien con el álgebra lineal y las operaciones de matriz / matriz, ya que parece que han estado haciendo algunas optimizaciones adicionales en las operaciones subyacentes: si quieres vencer a Matlab allí, necesitarías una biblioteca BLAS / LAPACK optimizada de manera similar.
Como lenguaje interpretado, Matlab pierde tiempo cada vez que se llama a una función de Matlab, debido a una sobrecarga interna, que tradicionalmente significaba que los bucles de Matlab eran lentos. Esto se ha aliviado un poco en los últimos años gracias a la mejora significativa en el compilador de JIT (búsqueda de preguntas de "rendimiento" en Matlab on SO por ejemplos). Como consecuencia de la sobrecarga de llamadas de función, todas las funciones de Matlab que no se han implementado en C / C ++ detrás de las escenas (llamar edit functionName
para ver si está escrito en Matlab) corre el riesgo de ser más lenta que una contraparte de C / C ++.
Finalmente, Matlab intenta ser amigable para el usuario y puede realizar comprobaciones de entrada "innecesarias" que pueden llevar tiempo (debido a la sobrecarga de llamadas a la función). Por ejemplo, si sabe que ismember
obtiene las entradas ordenadas, puede llamar a ismembc
directamente (la función compilada detrás de la escena), ahorrando bastante tiempo.
Tu pregunta es difícil de responder. En general, C ++ es más rápido, pero si utiliza los algoritmos bien escritos de Matlab, puede superar a C ++. En algunos casos, Matlab puede paralelizar su código, que se tiene que hacer manualmente en muchos casos para C ++. Mathlab puede exportar tipo de código C ++.
Así que mi conclusión es que debe medir el rendimiento de ambos programas para obtener una respuesta. Pero luego se comparan sus dos implementaciones y no Matlab y C ++ en general.
Vi una mejora de velocidad 5.5x al cambiar de MATLAB a C ++. Esto fue para un controlador de robot: montones de bucles y resolución de oda. Pasé muchas horas tratando de optimizar el código MATLAB, apenas optimizando el C ++ (estoy seguro de que podría haber sido 10 veces más rápido con un poco más de esfuerzo).
Sin embargo, fue fácil agregar una GUI para el código MATLAB, por lo que aún la uso más a menudo. Como han dicho otros, fue bueno hacer un prototipo primero en MATLAB. Eso hizo que la implementación en C ++ sea mucho más simple.