1 / 145

Supports d’exécution pour grappes de machines SMP

Supports d’exécution pour grappes de machines SMP. Raymond Namyst Projet INRIA ReMaP LIP, ENS Lyon. Plan. Multithreading Introduction et rappels Exploitation efficace des machines SMP Ordonnancement mixte, activations Multithreading distribué Modèles de programmation

alban
Télécharger la présentation

Supports d’exécution pour grappes de machines SMP

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Supports d’exécution pour grappes de machines SMP Raymond Namyst Projet INRIA ReMaP LIP, ENS Lyon

  2. Plan • Multithreading • Introduction et rappels • Exploitation efficace des machines SMP • Ordonnancement mixte, activations • Multithreading distribué • Modèles de programmation • Intégration des threads et des communications • Conclusion • Pas si simple…

  3. Multithreading Introduction et rappels

  4. Rappel : les processus lourds • Caractéristiques • Entité active directement supportée par l’OS • Flot d’exécution • Espace d’adressage privé • Ressources systèmes • Exécution séquentielle • Coût de gestion élevé • Allocation des ressources • Appels systèmes

  5. processeur processeur processeur Processus lourds • Ressources “noyau” + données “utilisateur” Espace utilisateur Processus Processus Processus Ordonnanceur Noyau

  6. Threads : Motivations • Difficulté de programmation • Fil d’exécution unique  une seule chose à la fois ! • Partage de données laborieux • Réactivité aux sollicitations externes • Performances • Opérations de base coûteuses • Recouvrement des opérations d’E/S difficiles

  7. Simplicité de programmation • Objectif • Mener plusieurs activités indépendantes au sein d’un processus • Exemples • Simulations • Serveurs de fichiers • Systèmes d’exploitation (!) • Seule solution (?) • Automate à états finis implanté « à la main » (sauvegardes d’états)

  8. Structure d’un OS monolytique • Exemple • Séquence infinie d’opérations courtes • Ordre et fréquence des scrutations ? for (;;) { if(networkMsgIn()) getNetworkMsg(); if(kbdReady()) getKey(); if(diskBlockReady()) handleDiskBlock(); … }

  9. Systèmes multiprogrammés • Exécution indépendante des activités • Concurrence entre les différents traitements for (;;) { wait for key stroke; getKey(); } for (;;) { wait for network msg; getNetworkMsg(); } for (;;) { wait for disk block; handleDiskBlock(); }

  10. Processus serveur classique • Sérialisation des requêtes • Pas de recouvrement des E/S • Exploitation SMP délicate • Prise en compte de priorités ? client serveur OS OS

  11. Sur l’efficacité des E/S • Caractéristiques du serveur de fichiers • Tps de traitement d’une requête = 15ms • Tps supplémentaire pour l’accès disque = 75ms (pour 1/3 des requêtes) • Débit sans/avec recouvrement des E/S • Sans recouvrement • 25 requêtes/seconde • Avec recouvrement • 33.33 requêtes/seconde (+33%)

  12. Les processus légers • Principe • Détacher flot d’exécution et ressources • Introduits dans divers langages & systèmes • Programmation concurrente • Recouvrement des E/S • Exploitation des architectures SMP thread ressources

  13. Caractéristiques de base • Thread = pile + contexte • Partage de ressources • Code, tas, … : espace d’adressage • Fichiers ouverts • Etc. • Opérations de base performantes • Création, destruction • Synchronisation, commutation de contextes • Création d’un processus léger • Adresse de fonction à exécuter + paramètres

  14. Performance des threads • Opérations critiques • Création/destruction (gestion mémoire) • Changement de contexte (temps-partagé) • Synchronisation (mode utilisateur) • Programme d’évaluation • Création d’une activité (processus, thread)+ synchronisation (terminaison de l’activité)

  15. Repères historiques • L’ancêtre : les coroutines • Entrelacement explicite des exécutions • Langages : Simula (67), Modula2 (82) • Primitives clés : create + resume • Les threads dans les systèmes • Cthread (Mach) -> DecThread -> PThread (~90) • Chorus, Solaris (87), winNT, IRIX, Linux, etc. • Les threads dans les langages • Ada (83), Java, etc. • C++ //, Eiffel //, etc.

  16. Multithreading Premier contact

  17. L’interface POSIX-Threads • Interface de programmation standard pour Unix • Portabilité des applications • Solaris, IRIX, HP-UX, Linux, etc. • Fonctionnalités • Création/destruction de threads • Synchronisation • Ordonnancement, priorités • Signaux • Etc.

  18. Exemple: création • Création d’un nouveau thread • Éventuels attributs dans la structure attr • Exécution de start_func avec le paramètre arg • *pid est l’identificateur du thread créé int pthread_create( pthread_t *pid, pthread_attr_t *attr, void * (*start_func)(void *), void *arg);

  19. Attente de fin d’exécution • Attente de la terminaison du thread pid • Récupération de son code de retour status • On peut contourner ce mécanisme en « détachant » les threads : int pthread_join( pthread_t pid, void **status); int pthread_detach( pthread_t pid);

  20. « Hello World! » #include <stdio.h> #include <pthread.h> void *func(void *arg) { printf(“Thread %x says %s\n”, pthread_self(), arg); return NULL; } int main(void) { pthread_t pid; pthread_create(&pid, NULL, func, “Hello World!”); printf(“This is the main thread\n”); pthread_join(pid, NULL); return 0; }

  21. Attributs • Ensemble fixé de caractéristiques • Utilisé à l’initialisation • Threads, verrous, variables de condition, etc. • Threads • Priorité • Pile : taille, emplacement • Détaché : oui/non • Type d’ordonnancement • Verrous • Inversion de priorités, récursivité

  22. Attributs : exemple #include <stdio.h> #include <pthread.h> void *handle_request(void *arg) { … } int main(void) { … pthread_attr_t attr; for(;;) { fd = accept(sock, …); pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(NULL, &attr, handle_request, fd); } }

  23. Exemple bis : pile • À manipuler avec précaution ! • Quelle taille de pile choisir ? • Comment prévenir/détecter les débordements ? pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 128*1024); pthread_create(NULL, &attr, func, NULL);

  24. Le standard OpenMP • Interface pour écrire des applications multithreads portables (sur SMP) • Directives de compilation (C, C++, Fortran)+ routines • Objectif = simplicité + portabilité • Constructeurs + fabricants de logiciels + etc. • Modèle de programmation • « Fork-Join » • Parallélisation des boucles (#pragma omp)

  25. Multithreading Partage mémoire efficace

  26. Les threads et la mémoire • Chaque thread possède sa propre pile • Variables locales « privées » (visibilité) • Les threads partagent l’espace d’adressage • Variables globales • Tas (malloc) • Variables locales (piles) également ! • Intérêt • Communications par pointeurs ! • Parallélisation de programmes séquentiels aisée ?

  27. Problèmes de réentrance • Exemple simple : int glob = 0; void *inc(void *arg) { int i; for(i=0; i<100; i++) glob++; } int main(void) { pthread_create(&t1, NULL, inc, NULL); pthread_create(&t2, NULL, inc, NULL); pthread_join(t1, NULL); pthread_join(t2, NULL); printf(“glob = %d\n”, glob); } Résultat ?

  28. Mov @glob, $r1 Inc r1 Mov @glob, $r1 Inc r1 Mov $r1, @glob … Mov $r1, @glob Mov @glob, $r1 Inc r1 Mov @glob, $r1 Inc r1 Mov $r1, @glob … Explication glob++ n’est pas forcément une opération atomique Scénario d’exécution concurrente par 2 threads : Mov @glob, $r1 ; charger Inc r1 ; incrémenter Mov $r1, @glob ; enregistrer Mov $r1, @glob

  29. Outils pour la synchronisation • Exclusion mutuelle : les verrous • Synchronisations plus complexes : • Variables de condition (cf moniteurs de Hoare) • pthread_cond_wait • pthread_cond_signal, pthread_cond_bcast int glob = 0; void *inc(void *arg) { for(i=0; i<100; i++) { pthread_mutex_lock(&mutex); glob++; pthread_mutex_unlock(&mutex); } }

  30. Code réentrant • « code demeurant correct lorsqu’il est exécuté simultanément par plusieurs threads » • Exemples typiques • Fonction n’utilisant que des variables locales • Code protégé par un verrou • Quid du code que l’on écrit pas soi-même ? • Malloc, free, …, la bibliothéque standard • Fonctions « MT-safe » • Option –D_REENTRANT • Certains prototypes changent…

  31. Importance de la synchro. • Cohérence séquentielle de la mémoire ? • Compilateurs/Optimiseurs • Instructions réordonnées • Processeurs modernes • Ecritures réordonnées • On ne peut pas supposer l’ordre des écritures • Primitives de synchronisation • Agissent comme des « barrières mémoire »

  32. Variables spécifiques • Pb : comment gérer les variables globales « privées » int my_x; void g(void) { …my_x… } void f(void) { my_x = do_compute(); … g(); }

  33. Variables spécifiques • Principe • Variable accessible à partir d’une clé • Allocation globale (souvent à l’initialisation) • pthread_setspecific(clé, valeur) • pthread_getspecific(clé) -> valeur • Exemple : la variable errno • Fichier errno.h #ifdef _REENTRANT #define errno (*__errno_location()) #else extern int errno; #endif

  34. Multithreading Quelques idées reçues ?

  35. A propos d’efficacité… • Les threads sont-ils toujours meilleurs que MPI sur architectures SMP ? • Approche « processus communicants » • Communications pénalisantes (copies) • Surcoût en utilisation de ressources • Recouvrement plus difficile • Approche « processus légers » • Synchronisations additionnelles • Accès aux variables spécifiques coûteux

  36. Exploitation efficacedes machines SMP Quelle catégorie de threads ?

  37. Process Process Process Scheduler Scheduler Scheduler processor processor processor Multithreading utilisateur • Deux ordonnanceurs indépendants : User Space OS Kernel

  38. Process Process Process Scheduler processor processor processor Multithreading noyau • Un seul ordonnanceur : User Space OS Kernel

  39. Process Process Process Scheduler Scheduler Scheduler processor processor processor Multithreading mixte • Deux ordonnanceurs coopérants User Space OS Kernel Note: Quid des appels systèmes bloquants ?

  40. Performances • Athlon 1.4GHz, DDR2100 • Alpha 500MHz

  41. E/S et ordonnancement • Threads noyaux : OK • Threads utilisateurs • Appel bloquant -> blocage du processus entier • Threads mixtes • Idem au bout d’un certain nombre ! • Solutions ? • Appels toujours non-bloquants (polling) • Appels effectués par des threads dédiés • Support système spécifique

  42. Exploitation efficacedes machines SMP Scheduler Activations

  43. Temps CPUperdu syscall I/O request interrupt • …on voudrait : CPU utilisé Espace utilisateur Espace noyau Matériel Recouvrement des E/S • Au lieu de Espace utilisateur Espace noyau Matériel

  44. Scheduler Activations • Introduit par [Anderson et al. 91] • Idée: la coopération entre les deux ordonnanceurs est bidirectionnelle • L’ordonnanceur utilisateur utilise des appels systèmes • L’ordonnanceur noyau utilise des upcalls! • Upcalls • Informe l’application des événements noyaux • Activations • Autant d’activations en exécution que de processeurs • Contrôlées par le noyau • Principe mis en œuvre dans Solaris

  45. Illustration du principe Process User scheduler

  46. new Illustration du principe Process

  47. new Illustration du principe Process

  48. Appel système bloquant Illustration du principe • Déroulement d’un appel bloquant… Process

  49. New + blocked Illustration du principe • Déroulement d’un appel bloquant… Process

  50. Appel terminé Illustration du principe • Déroulement d’un appel bloquant… Process

More Related