10
votes

Dois-je conserver la mémoire dans Matlab en déclarant des variables globales au lieu de les transmettre comme des arguments?

Je suis nouveau à Matlab, ce n'était pas dans la description de poste et j'ai été obligé de reprendre la personne qui a écrit et maintenu le code que mon entreprise utilise. La vie est dure.

Le gars à partir de laquelle je prends la relève m'a dit qu'il a déclaré tous les grands vecteurs de données comme global , pour enregistrer la mémoire. Plus spécifiquement, de sorte que lorsqu'une fonction appelle une autre fonction, il ne crée pas de copie des données lorsqu'il le transmet.

est-ce vrai? J'ai lu Stratégies d'utilisation efficace de la mémoire , et il dit que

Lorsque vous travaillez avec de grands ensembles de données, sotez que MATLAB constitue une copie temporaire d'une variable d'entrée si la fonction appelée modifie sa valeur. Cela double temporairement la mémoire requise pour stocker le tableau, ce qui provoque la génération de MATLAB pour générer une erreur si une mémoire suffisante n'est pas disponible.

Il dit quelque chose de très similaire dans Allocation de mémoire pour tableau #fonction Arguments :

Lorsque vous passez une variable à une fonction, vous transmettez en réalité une référence aux données que la variable représente. Tant que les données d'entrée ne sont pas modifiées par la fonction étant appelée, la variable de la fonction d'appel et la variable dans le point de fonction appelé sur le même emplacement en mémoire. Si la fonction appelée modifie la valeur des données d'entrée, Matlab apporte une copie de la matrice d'origine dans un nouvel emplacement en mémoire, des mises à jour qui copient la valeur modifiée et indiquent la variable d'entrée dans la fonction appelée à ce nouveau tableau.

est-il vrai que l'utilisation de global peut être meilleure? Il semble que un peu négligé déclarer parfaitement toutes les grandes données comme global au lieu de s'assurer qu'aucun code ne modifie son argument d'entrée. Ai-je tort? Cela améliore-t-il vraiment l'utilisation de la RAM?


3 commentaires

Pourquoi ne surveillez-vous pas l'utilisation du RAM pour voir ce qui est préférable? Je ne pense pas que votre question soit différente de toute autre performance. Vous devez profiler votre code. Il semble que vous puissiez écrire deux boucles et tester si une variable comme entrée globale ou comme une fonction est meilleure lorsque votre code modifie les données de l'entrée (si elle le fait du tout, car la mémoire n'est que "doublée" quand elle le fait). Désolé de ne pas donner la réponse, mais il y a trop de gotchas lorsque la performance compte.


Votre absolument correct, mais j'ai quand même posé la question, car je craignais que c'était une question de style de codage et non seulement de la mémoire. Tant pis...


Couple des choses qui pourraient aider: "Profil sur -Memory" suivra l'allocation dans le profileur Matlab. Et si vous utilisez des objets de "poignée" R2008A +, de nouveaux objets de style peuvent passer par référence, qui conserveront la mémoire, mais une meilleure contrôle de la portée de la portée que les globaux.


4 Réponses :



3
votes

La solution me semble un peu étrange. Comme vous l'avez déjà découvert, il ne devrait pas avoir d'impact significatif sur l'utilisation de la mémoire si la fonction appelée ne modifie pas la matrice de données. Toutefois, si la fonction appelée modifie la matrice de données, il y a une différence fonctionnelle : dans un cas (rendant le tableau de données global), la modification a un impact sur le reste du code, dans l'autre cas. (en passant comme référence) Les modifications ne sont que locales et temporaires.


0 commentaires

3
votes

Je pense que vous avez à peu près répondu à votre propre question, mais quelques références supplémentaires seraient bonnes ici:

J'ai fait une vidéo à ce sujet:

http: // blogs. mathworks.com/videos/2008/09/16/new-location-Alt-Memory-ALLOCATION /

similaire à ce que Loren a parlé d'ici:

http: // blogs.mathworks.com/loren/2006/05/10/Memory-management-function-and-and-variables/

-Dogu


0 commentaires

4
votes

Cette réponse peut être quelque peu tangentielle, mais un sujet supplémentaire qui porte ici est l'utilisation de Fonctions imbriquées pour gérer la mémoire.

Comme a déjà été établi dans d'autres réponses, il n'y a pas besoin de Global variables si les données que vous avez passe à la fonction n'est pas modifié (puisqu'il sera adopté par référence). Si est modifié (et est ainsi passé par valeur), à l'aide d'une variable global sauvegarder vous enregistrera la mémoire. Toutefois, Global variables peut être un peu "incroyable" pour les raisons suivantes:

  • Vous devez faire une déclaration comme Global Varname partout où vous en avez besoin.
  • Il peut être conceptuellement d'essayer de garder une trace de quand et comment ils sont modifiés, surtout s'ils sont répartis sur plusieurs fichiers M.
  • L'utilisateur peut facilement casser votre code avec un mal placé clair global , qui efface tous les variables globales .

    Une alternative à Global variables a été mentionnée dans Le premier ensemble de documentation que vous avez citée : fonctions imbriquées. Immédiatement après la citation que vous avez citée est un exemple de code (que j'ai formaté légèrement différemment ici): xxx

    dans cet exemple, la fonction setRowval est niché à l'intérieur de la fonction myfun . La variable A dans l'espace de travail de myfun est accessible dans setRowval (comme s'il avait été déclaré global dans chaque ). La fonction imbriquée modifie cette variable partagée, évitant ainsi toute allocation de mémoire supplémentaire. Vous n'avez pas à vous soucier de l'utilisateur d'effacer par inadvertance rien et (à mon avis), il est un peu plus propre et plus facile à suivre que de déclarer Global variables.


0 commentaires