2009-08-11 17 views
10

Soy nuevo en MATLAB, no estaba en la descripción del trabajo y me he visto obligado a reemplazar a la persona que escribió y mantuvo el código que usa mi empresa. La vida es dura¿Conservo memoria en MATLAB declarando las variables globales en lugar de pasarlas como argumentos?

El chico del que estoy tomando el control me dijo que declaró todos los vectores de big data como global, para ahorrar memoria. Más específicamente, de modo que cuando una función llama a otra función, no crea una copia de los datos cuando la pasa.

¿Es esto cierto? He leído Strategies for Efficient Use of Memory, y se dice que

Cuando se trabaja con grandes conjuntos de datos, tenga en cuenta que MATLAB hace una copia temporal de una variable de entrada si la función llamada modifica su valor. Esto duplica temporalmente la memoria requerida para almacenar la matriz, lo que hace que MATLAB genere un error si no hay suficiente memoria disponible.

Dice algo muy similar en Memory Allocation For Array #Function Arguments:

Cuando se pasa una variable a una función, que están pasando en realidad una referencia a los datos que representa la variable. Siempre que los datos de entrada no sean modificados por la función a la que se llama, la variable en la función de llamada y la variable en la función llamada apuntan a la misma ubicación en la memoria. Si la función llamada modifica el valor de los datos de entrada, entonces MATLAB hace una copia de la matriz original en una nueva ubicación en la memoria, las actualizaciones que copian con el valor modificado y apunta la variable de entrada en la función llamada a esta nueva matriz.

¿Es verdad que usar global puede ser mejor? Parece un poco descuidado declarar alegremente todos los datos grandes como global, en lugar de asegurarse de que ninguno de los códigos modifica su argumento de entrada. ¿Me equivoco? ¿Esto realmente mejora el uso de RAM?

+2

¿Por qué no controlas el uso de RAM para ver qué es mejor? No creo que tu pregunta sea diferente a las demás. Necesita perfilar su código. Parece que puede escribir dos bucles y probar si una variable como entrada global o como función es mejor cuando su código cambia los datos de la entrada (si es que lo hace, porque la memoria solo se "duplica" cuando lo hace). Perdón por no dar la respuesta, pero hay demasiados problemas cuando el rendimiento importa. – inerte

+0

Es absolutamente correcto, pero de todos modos hice la pregunta, ya que me preocupaba que esto fuera una cuestión de estilo de codificación y no solo de memoria. Oh, bueno ... – scraimer

+2

Junte cosas que podrían ayudar: "profile on -memory" rastreará la asignación en el perfilador de Matlab. Y si está utilizando R2008a +, los objetos de "manejar" nuevos estilos pueden pasar por referencia, lo que conservará la memoria pero tendrá un mejor control del alcance que los globales. –

Respuesta

6

En mi experiencia, siempre que ninguno de los códigos modifique los datos grandes, el uso de memoria es el mismo, independientemente de si utiliza una variable global o un argumento de entrada, como dicen los documentos de Matlab. Más información está en este blog post por un empleado de MathWorks.

Hay bastante folclore sobre los problemas de rendimiento en Matlab y no todo es correcto. Las partes internas de Matlab han cambiado bastante. Puede ser que en una versión anterior sea mejor usar una variable global.

+1

+1 y responde por lo cool, por usar también el blog de Loren. Ella es una usuaria aquí! - http://stackoverflow.com/users/113700/loren – scraimer

2

La solución me parece un poco extraña. Como ya descubrió, no debería tener un impacto significativo en el uso de la memoria si la función llamada no modifica la matriz de datos. Sin embargo, si la función llamada modifica la matriz de datos, existe una diferencia funcional: En un caso (haciendo que la matriz de datos sea global), el cambio tiene un impacto en el resto del código, en el otro caso (pasándolo como referencia) las modificaciones son solo locales y temporales.

4

Esta respuesta puede ser algo tangencial, pero un tema adicional que se menciona aquí es el uso de nested functions para administrar la memoria.

Como ya se ha establecido en otras respuestas, no hay necesidad de global variables si los datos que está pasando a la función no se modifican (ya que se pasarán por referencia). Si se modifica (y por lo tanto se pasa por valor), utilizando una variable global en su lugar, le ahorrará memoria. Sin embargo, global variables pueden ser algo "tosco" por las siguientes razones:

  • usted tiene que hacer una declaración como global varName todas partes que los necesite.
  • Puede ser conceptualmente un poco complicado intentar realizar un seguimiento de cuándo y cómo se modifican, especialmente si están distribuidos en múltiples archivos-m.
  • El usuario puede romper fácilmente su código con clear global mal ubicado, que borra todas las variables globales.

Se ha mencionado una alternativa a las variables global en : funciones anidadas. Inmediatamente después de la cita que se cita es un ejemplo de código (que he formateado de forma ligeramente diferente aquí):

function myfun 

    A = magic(500); 
    setrowval(400, 0); 
    disp('The new value of A(399:401,1:10) is') 
    A(399:401,1:10) 

    function setrowval(row, value) 
    A(row,:) = value; 
    end 

end 

En este ejemplo, la función es setrowval anidada dentro de la función myfun. La variable A en el espacio de trabajo myfun es accesible dentro de setrowval (como si hubiera sido declarada global en cada una). La función anidada modifica esta variable compartida, evitando así cualquier asignación de memoria adicional. No tiene que preocuparse de que el usuario borre algo inadvertidamente y (en mi opinión) es un poco más limpio y más fácil de seguir que declarar global variables.

Cuestiones relacionadas