>
> >
PlaFRIM2 - avancé : contexte d’utilisation
en cours de rédaction
Comment utiliser "au mieux" PlaFRIM2, avec ses contraintes, pour exécuter "au mieux" l’ensemble des calculs à effectuer, en respectant "au mieux" les objectifs prioritaires.
Les objectifs scientifiques possibles
- la qualité des résultats
- l’objectif est ici d’effectuer le plus rapidement possible l’ensemble des calculs compte tenu des contraintes d’exécution sur PlaFRIM, même si individuellement, les temps de calculs des instances sont perturbés
- l’exactitude des temps individuels de calculs
- on cherche ici a effectuer chaque calcul le plus rapidement possible et à avoir une mesure précise de ce temps. Les calculs doivent être exacts aussi bien sûr !
- dans l’idéal, chaque exécution de la même instance devrait prendre le même temps
Dans une phase intermédiaire de mise au point / défrichage, on peut se contenter de temps de calculs individuels inexactes (dans un certain pourcentage à mesurer) mais avec un temps d’exécution global très réduit.
Les contraintes morales
- respect des autres utilisateurs : la plateforme de calcul est utilisée par l’ensemble de la communauté. il faut donc veiller à utiliser les ressources de la manière la plus efficace et rationnelle possible :
- ne pas monopoliser de nœuds de calcul sans les utiliser
- ne pas utiliser qu’un ou quelques cœurs sur une machine qui en comporte plusieurs dizaine. Sauf dans les cas suivant :
- saturation de la mémoire en utilisant tous les cœurs
- besoin de faire des mesures de temps ultra précises (voir ci dessous)
- respect de l’environnement : les nœuds de calculs consomment beaucoup d’énergie électrique ce qui est, d’une façon ou d’une autre, une nuisance pour l’environnement.
- ne pas faire de calcul inutiles ou dont on peut se passer
- optimiser raisonnablement son implémentation et ses algorithmes pour réduire les temps de calcul
Les contraintes de Plafrim
- contraintes liées aux ressources physiques
- la taille mémoire des nœuds de calcul (dépend du cluster utilisé)
- le nombre de cœurs de chaque nœuds
- la taille mémoire par cœur (rapport entre les deux valeurs précédentes)
- les contraintes d’occupation
- le temps maximum utilisable (dépend de la partition choisie)
- le nombre de nœuds maximum utilisable (dépend de la partition choisie)
- le nombre de jobs est soumis à plusieurs limites
- nombre maximum de jobs en attente (total et par utilisateurs)
- nombre maximum de jobs running (total et par utilisateurs)
- nombre maximum de jobs running (total et par utilisateurs) par partition
- ...
Mesure de temps ultra précises
- Procéder par étapes. De plus en plus précise (gaspillage croissant !)
- 1- un processus par cœur : calcul de l’ordre de grandeur du temps nécessaire
- 2- un processus par socket / cache L3 : doit donner des temps identiques au cas 2
- 3- un processus par nœud : mesure la plus précise. à utiliser uniquement pour la finalisation des temps de calculs juste avant de soumettre un article.
A savoir :
- gestion de l’aléa : si votre code ou des librairies que vous utilisez utilise des méthode statistiques / des tirages au sort, il vous faut fixer les germes/graines servant à initialiser les générateur pseudo aléatoire, de façon a rendre reproductible vos instances de calcul
- aléa inévitable : certaines librairies de calculs, comme CPLEX, utilisent des compteurs de temps pour limiter certaines phases de recherche de solution. Si une solution est trouvée dans le temps imparti, un certain comportement est déclenché, et un autre comportement se déclenche dans l’autre cas. Une infime variation de temps peut ainsi engendrer des comportements très différents, et des temps de calculs et des solutions résultantes très différents.
- pas d’entrée/sortie I/O : les entrées/sorties (ex : lecture/écritures de données sur disque, communications réseau) sont par nature de durées variables en fonction de la charge de la machine, des serveurs de fichiers, des autres nœuds de la plateforme de calcul et des réseaux d’interconnexions. Pour faire des mesures précises, il ne faut donc pas comptabiliser ces temps, ou les comptabiliser à part, ou les moyenner.
- bind to core : limiter les changements de contextes en utilisant des paramètres d’exécution qui fixent les processus sur des cœurs de calculs dédiés.
- invalidation de cache : éviter les invalidation de cache instruction / cache data
- warmup / préchauffage : faire tourner une première fois le code sans chronométrer de manière à pré-remplir les buffers caches, précharger (en les lisant) tous les binaires et librairies nécessaires, puis relancer une deuxième fois en chronométrant. (ex pour mettre en cache un programme et ses librairies partagées en forçant leur lecture intégrale - à condition qu’il n’y ai pas de chargements dynamiques ultérieurs d’autres librairies -