IMB > cellule > Moyens de calcul

PLAFRIM2 avancé : partie pratique

... en travaux ...

Informations pour une utilisation avancée de PLAFRIM2.

Jobs sur plusieurs noeuds

Pour exécuter correctement des jobs sur plusieurs nœuds, il est nécessaire de bien comprendre le fonctionnement des commandes slurm.

Plusieurs éléments doivent être pris en considération :

  • la manière dont les nœuds de calcul sont choisis (répondant à des contraintes d’inclusion, d’exclusion, de type de nœuds, de taille mémoire, ...)
  • le nombre de tâches (tasks) (processus au sens UNIX) à exécuter. Typiquement, des commandes comme srun ou mpiexec se chargent de lancer (spawn) un certain nombre de tâches identiques sur l’ensemble de cœurs de calculs.
  • la nature des taches : mono ou multi thread. Le nombre de cœurs attendu par tâche se règle avec l’option -c.
    • En précisant -c1 vous demandez à avoir une tache par cœur de calcul : c’est ce que l’on souhaite habituellement pour des tâches mono thread. -** En précisant -c2 vous demandez à avoir 2 cœurs pour chacune de vos tâches.
  • la manière d’affecter les tâches aux cœurs de calculs -** de manière imposée (bind) : on impose à chaque tâche de s’exécuter sur un ou plusieurs cœurs bien précis, que l’on peut choisir très précisément (mapping) -** de manière libre : les tâche sont libres de se promener d’un cœur à l’autre (au sein d’un même nœuds de calcul) en fonction de la charges de ces derniers.
  • la manière d’affecter la mémoire aux tâches
    • de manière imposée (bind) et précise (mapping)

Il faut aussi connaître la terminologie utilisée par slurm pour décrire les noeuds de calcul :

  • node : noeud de calul = un ordinateur / une machine de calcul. Carte mère + disque dur (optionnel) + mémoires + processeurs. Un node contient un ou plusieurs socket .
  • socket : un boîtier contenant des processeurs et relié de manière privilégié avec une zone mémoire. Un socket contient un ou plusieurs core. Un socket est généralement associé à un unique cache L3 qui est du coup partagé entre les différent core qu’il contient.
  • core : un cœur de calcul. Un cœur a généralement des caches L1 et L2 qui lui sont propres. Un core peut contenir un ou plusieurs thread.
  • thread : plus petite unité de calcul autonome identifiée par slurm. Les cœurs classique n’ont généralement qu’un seul thread.

La notion de CPU (processing unit) de slurm correspond à l’unité de traitement la plus petite : (core dans la plus part des cas, ou thread si les core ont plus d’un seul thread). C’est pourquoi on parle souvent de core et non de thread.

Pourquoi est-ce important ?

Pour des raisons de performance.

Pour avoir les meilleurs performances, il faut généralement que les tâches soient bindées sur les cœurs de calcul pour éviter les invalidations de cache provoquées par les migrations et qu’elles manipulent des données présentes sur les bancs mémoire directement raccordés au cœur de calcul concerné.

On peut cependant (en mixant slurm et mpi) se retrouver dans des situations de binding très défavorable où toutes les tâches sont bindées sur un unique core, pendant que tous les autres cores se tournent les pouces...

Le NUMA : Non Uniforme Memory Access. Ce term désigne les architectures où le temps d’accès à la mémoire est variable. C’est le cas des machines multi socket. La mémoire proche (raccordée à un socket) est plus rapidement accessible que les mémoires éloignées (nécessitant de passer par un autre socket.

Les options correspondantes les plus utilisées :

  • -N : nombre de nœuds demandés (par défaut 1). Ex : -N4 pour avoir 4 noeuds
    • -N2-6 : permet de préciser un nombre min et un nombre max.
  • -n : nombre de tâches demandées (par défaut 1 par nœud). Exemple : -n6
  • -c : nombre de CPU par tâches (implicitement 1). Exemple -c2 pour des tache multithread à 2 threads.

Quelques exemples en « slurm pur » (spawn avec srun)

  • -N2 : demande 2 noeuds. srun lancera une tache par nœud, utilisant 2 cœurs de calcul.
  • -N2 -n6 : demande 2 noeuds supportant un total de 6 taches. srun lancera 3 taches sur chacun des 2 noeuds (3x2=6). 6 coeurs sont utilisés.
  • -N2 -c1 : demande 2 noeuds avec 1 CPU par tache. Si les noeuds disposent de 24 CPU, 48 taches seront lancées par srun, 24 sur chacun des 2 noeuds. 48 coeurs sont utilisés.
    • -N2-4 -c1 : Demande entre 2 et 4 noeuds et lance une tache par coeur. Permet de gérer automatiquement l’adaptation au nombre de nœuds effectivement alloué en fonction des machines retenues.
  • -N2 -c6 : demande 2 noeuds pour executer 2 taches multithread à 6 threads.
  • -N2 -n4 -c6 : demande 2 noeuds pour executer un total de 4 taches multithread à 6 threads par tache. 4x6=24 coeurs utilisés, 12 sur chaque noeud.