Question

Mon problème est le suivant:

J'ai un script Perl qui utilise beaucoup de mémoire (comportement attendu en raison de la mise en cache). Cependant, j'ai remarqué que plus je fais de la mise en cache, plus le processus est lent et le processus passe la plupart du temps en mode veille.

Je pensais que la pré-allocation de mémoire au processus pourrait accélérer les performances.

Quelqu'un a-t-il des idées ici?

Mettre à jour :

Je pense que je ne suis pas très clair ici. Je vais poser la question plus clairement:

Je ne cherche pas les moyens de pré-allouer à l'intérieur du script Perl. Je ne pense pas que cela m'aiderait beaucoup ici. Ce qui m’intéresse, c’est un moyen de dire à OS d’allouer une quantité de mémoire X à mon script perl afin qu’il ne soit pas mis en concurrence avec d’autres processus intervenant plus tard.

Supposons que je ne peux pas me permettre d’utiliser la mémoire. Bien que, j'explore des moyens de réduire cela aussi, mais ne vous attendez pas à beaucoup d'amélioration là-bas. Pour votre information, je travaille sur une machine Solaris 10.

Était-ce utile?

La solution

Ce que j'ai compris de votre commentaire et de vos commentaires est le suivant:

  • Votre programme ralentit lorsque l'utilisation de la mémoire augmente
  • Votre pogramme passe de plus en plus de temps en sommeil et non en informatique.

Eplanation la plus probable: Dormir signifie attendre qu'une ressource devienne disponible. Dans ce cas, la ressource la plus probable est la mémoire. Utilisez la commande vmstat 1 pour vérifier. Jetez un oeil à la colonne Sr. Si le nombre de pages dépasse régulièrement les 150, le système s'efforce de libérer des pages pour satisfaire la demande. Ceci s’accompagne d’une forte activité dans les colonnes pi, po et fr.

Si tel est le cas, vos meilleurs choix sont:

  • Mettez à niveau la mémoire système pour répondre à la demande
  • Réduisez l'utilisation de la mémoire à un niveau approprié pour le système concerné.

La préallocation de mémoire ne va pas aider. Dans les deux cas, la demande de mémoire dépassera la mémoire principale disponible à un moment donné. Le noyau devra alors décider quelles pages doivent être maintenant en mémoire et quelles pages peuvent être effacées et réutilisées pour les pages dont le besoin est le plus urgent. Si toutes les pages dont vous avez régulièrement besoin (l'ensemble de travail) dépassent la taille de la mémoire principale, le système déplace constamment les pages de et vers le stockage secondaire (permutation). On dit alors que le système se débat et qu'il ne passe pas beaucoup de temps à faire un travail utile. Vous ne pouvez rien faire à ce propos, sauf en ajoutant de la mémoire ou en en utilisant moins.

Autres conseils

extrait d'un commentaire:

  

Les limites en matière de mémoire ne sont pas très sévères, mais l’empreinte mémoire augmente facilement et se chiffre en Go. Lorsque nous avons des processus concurrents pour la mémoire, cela devient très lent. Je souhaite réserver de la mémoire à partir du système d'exploitation de manière à minimiser les pertes, même lorsque trop d'autres processus surviennent. Jagmal

Prenons une tactique différente alors. Le problème ne concerne pas particulièrement votre script Perl. Au lieu de cela, tous les processus de la machine consomment trop de mémoire pour que la machine puisse la gérer telle que configurée.

Vous pouvez "réserver". mémoire, mais cela n'empêchera pas les battements. En fait, cela pourrait aggraver le problème, car le système d'exploitation ne saura pas si vous utilisez la mémoire ou si vous l'enregistrez simplement pour plus tard.

Je suppose que vous êtes la tragédie des biens communs . Ai-je raison de dire que de nombreux autres utilisateurs sont sur la machine en question? Si tel est le cas, il s’agit plus d’un problème social que technique. Vous avez besoin de quelqu'un (probablement l'administrateur système) pour intervenir et coordonner tous les processus de la machine. Ils devraient trouver les gâchis de mémoire les plus extravagants et travailler avec leurs programmeurs pour réduire le coût des ressources système. En outre, ils devraient organiser la planification des processus de manière à ce que l'allocation des ressources soit efficace. Enfin, ils peuvent avoir besoin de davantage de matériel ou de matériel amélioré pour gérer la charge système attendue.

Quelques questions que vous pourriez vous poser:

  • mes structures de données sont-elles vraiment utiles pour la tâche à accomplir?
  • dois-je vraiment mettre autant en cache?
  • puis-je jeter les données en cache après un certain temps?
my @array;
$#array = 1_000_000; # pre-extend array to one million elements,
                     # http://perldoc.perl.org/perldata.html#Scalar-values

my %hash;
keys(%hash) = 8192; # pre-allocate hash buckets 
                    # (same documentation section)

Ne connaissant pas votre code, je vais risquer ici de spéculer de manière farfelue sur le fait que ces techniques ne vont pas améliorer l'efficacité de votre script, mais que la pré-allocation pourrait vous aider un peu.

Bonne chance!

- Douglas Hunter

J'ai récemment redécouvert un excellent article de Randal L. Schwartz , qui inclut la préallocation. un tableau. En supposant que ce soit votre problème, vous pouvez tester la préallocation avec une variante de ce code. Mais assurez-vous de tester le résultat.

La raison pour laquelle le script ralentit avec la mise en cache peut être écrasé . Vraisemblablement, la mise en cache est censée augmenter les performances. Donc, une réponse rapide est: réduisez la mise en cache.

Il existe maintenant des moyens de modifier votre schéma de mise en cache afin d’utiliser moins de mémoire principale et d’éviter les thrashs. Par exemple, vous pouvez constater que la mise en cache dans un fichier ou une base de données plutôt que dans la mémoire peut améliorer les performances. J'ai constaté que la mise en cache du système de fichiers et de la base de données peut être plus efficace que la mise en cache d'application et peut être partagée entre plusieurs instances.

Une autre idée pourrait être de modifier votre algorithme pour réduire l'utilisation de la mémoire dans d'autres domaines. Par exemple, au lieu de mettre un fichier entier en mémoire, les programmes Perl ont tendance à mieux fonctionner, lecture ligne par ligne.

Enfin, avez-vous exploré le module Memoize ? Ce n'est peut-être pas immédiatement applicable, mais ce pourrait être une source d'idées.

Je n'ai pas encore trouvé le moyen de le faire.

Mais j’ai découvert que (voir this pour plus de détails)

  

Mémoire allouée aux lexicaux (c.-à-d.   mes variables ()) ne peuvent pas être récupérées ou   réutilisés même s’ils sortent du cadre.   Il est réservé au cas où les variables   revenir dans la portée. Mémoire allouée   aux variables globales peuvent être réutilisés   (au sein de votre programme) en utilisant   undef () ing et / ou delete ().

Donc, je pense qu’une possibilité ici pourrait être de vérifier si je peux réduire l’empreinte mémoire totale des variables lexicales à un moment donné.

On dirait que vous recherchez limite ou ulimit . Mais je soupçonne que cela fera échouer un script qui dépasse la limite, ce qui n’est probablement pas ce que vous voulez.

Une meilleure idée pourrait être de partager des données en cache entre les processus. Mettre des données dans une base de données ou dans un fichier fonctionne bien dans mon expérience.

Je n'aime pas le dire, mais si vos limites de mémoire sont aussi sévères, Perl n'est probablement pas le bon langage pour cette application. C serait un meilleur choix, je pense.

Vous pouvez notamment utiliser les zones solaris (conteneurs).
Vous pouvez placer votre processus dans une zone et y allouer des ressources telles que la RAM et les processeurs.
Voici deux liens vers des tutoriels:

  1. Guide pratique des conteneurs Solaris <> / a>
  2. Contrôle des ressources de zone dans le système d'exploitation Solaris 10 08/07

Bien que la pré-allocation ne soit pas conforme à vos attentes, vous pouvez également consulter les grandes options de taille de page afin que Perl demande au système d’exploitation davantage de mémoire pour votre programme, il la récupère. plus gros morceaux.

Voir Solaris Internals: prise en charge de plusieurs tailles de page pour plus d'informations sur le différence que cela fait et comment le faire.

Regardez http://metacpan.org/pod/Devel::Size .

Vous pouvez également intégrer une fonction c à cette fin.

Autant que je sache, vous ne pouvez pas allouer de mémoire directement à partir de Perl. Vous pouvez contourner ce problème en écrivant un module XS ou en utilisant une fonction C en ligne, comme je l’ai déjà mentionné.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top