c optimization matlab mex

El archivo de Matlab mex es lento en comparación con su equivalente directo en C



optimization (2)

No puedo explicar (y evitar) las diferencias de velocidad entre un programa Matlab mex y el programa C correspondiente sin interfaz Matlab. He estado perfilando un programa de análisis numérico:

int main(){ Well_optimized_code(); }

compilado con gcc 4.4 contra el equivalente de Matlab-Mex (dirigido a usar gcc44, que no es la versión actualmente soportada por Matlab, pero se requiere por otros motivos):

void mexFunction(int nlhs,mxArray* plhs[], int nrhs, const mxArray* prhs[]){ Well_optimized_code(); //literally the exact same code }

Realicé los tiempos como:

$ time ./C_version

vs.

>> tic; mex_version(); toc

La diferencia en el tiempo es asombrosa. La versión ejecutada desde la línea de comando demora en promedio 5.8 segundos. La versión en Matlab se ejecuta en 21 segundos. Por contexto, el archivo mex reemplaza un algoritmo en la caja de herramientas SimBiology que tarda unos 26 segundos en ejecutarse.

En comparación con el algoritmo de Matlab, tanto la versión C como la versión mex escalan linealmente hasta 27 subprocesos utilizando llamadas a openMP, pero a los fines del perfil, estas llamadas se inhabilitaron y se comentaron.

Las dos versiones se han compilado de la misma manera con la excepción de los indicadores necesarios para compilar como un archivo mex: -fPIC --shared -lmex -DMATLAB_MEX_FILE se aplica en la compilación / vinculación mex. Eliminé todas las referencias a los argumentos izquierdo y derecho del archivo mex. Es decir que no requiere entradas ni da salidas, es únicamente para crear perfiles.

El Gran y Glorioso Google me ha informado que el código de posición independiente no debe ser la fuente de la desaceleración y más allá de eso estoy perdido.

Cualquier ayuda será apreciada,

Andrés


Después de un mes de correos electrónicos con mis contactos en Mathworks, jugando con mi propio código y perfilando mi código de todas formas, tengo una respuesta; sin embargo, puede ser la respuesta más insatisfactoria que he tenido a una pregunta técnica:

La versión corta es "upgrade to Matlab versión 2011a (lanzada oficialmente la semana pasada), este problema ya se ha resuelto".

La versión más larga se refiere a un problema de los gastos generales asociados con la puerta de acceso mex en las versiones 2010b y anteriores. La mejor explicación que he podido extraer es que esta sobrecarga no se evalúa una sola vez, sino que pagamos un poco cada vez que una función llama a otra función que está en una biblioteca vinculada.

Si bien por qué ocurre esto me desconcierta, al menos es coherente con el perfil SHARK que hice. Cuando perfilo y comparo las diferencias entre la aplicación nativa y la aplicación mex, hay un patrón recurrente. El tiempo dedicado a las funciones que están en el código fuente que escribí para la aplicación no cambia. El tiempo dedicado a las funciones de la biblioteca aumenta un poco cuando se comparan las implementaciones nativa y mexicana. Las funciones en otra biblioteca utilizada para construir esta biblioteca aumentan mucho la diferencia. La diferencia de tiempo sigue aumentando a medida que avanzamos cada vez más hasta llegar a la implementación de BLAS.

Un par de funciones BLAS muy usadas fueron las principales culpables. Una función que tomó ~ 1% de mi tiempo de computación en la aplicación nativa estaba llegando al 30% en la función mex.

La implementación de la puerta de enlace mex parece haber cambiado entre 2010b y 2011a. En mi macbook, la aplicación nativa tarda unos 6 segundos y la versión mex tarda 6,5 ​​segundos. Esto es sobrecargado con lo que puedo lidiar.

En cuanto a la causa subyacente, solo puedo especular. Matlab tiene sus raíces en la codificación interpretativa. Dado que las funciones mex son bibliotecas dinámicas, supongo que cada biblioteca mex no tenía conocimiento de a qué se vinculó hasta el tiempo de ejecución. Dado que Matlab sugiere que el usuario rara vez usa mex y luego solo para pequeños fragmentos computacionalmente intensivos, supongo que los programas grandes (como los de resolución de ODE) raramente se implementan. Estos programas, como el mío, son los que más sufren.

He perfilado un par de funciones de Matlab que sé que se implementarán en C y compiladas usando mex (especialmente sbiosimulate después de llamar a sbioaccelerate en modelos cinéticos, parte de la caja de herramientas de SimBiology) y parece que hay algunas aceleraciones significativas. Por lo tanto, la actualización de 2011a parece ser más beneficiosa que la actualización semestral habitual.

La mejor de las suertes a otros codificadores con problemas similares. Gracias por todos los útiles consejos que me ayudaron a comenzar en la dirección correcta.

--Andrés


Recuerde que Matlab almacena matrices como columna principal y C / C ++ como fila principal. ¿Es posible que su estructura / algoritmo de bucle se repita en una fila de manera importante, lo que resulta en tiempos de acceso a la memoria deficiente en Matlab, pero los tiempos de acceso rápido en C / C ++?