wiki:MultiCourseTP7

Cours "Architecture des Systèmes Multi-Processeurs"

TP7 : Contrôleur DMA

(franck.wajsburt@…)

A. Objectifs

Le but de ce TP est d'analyser le fonctionnement d'un périphérique plus complexe que ceux analysés dans le TP6. Un périphérique possédant une capacité DMA (Direct Memory Access) se comporte à la fois comme un maître capable de lire ou d'écrire directement en mémoire, et comme une cible capable - comme n'importe quel périphérique - de recevoir des commandes provenant du système d'exploitation.

On utilise la même architecture que dans le TP5 et le TP6, mais on instanciera un seul processeur, et on activera le contrôleur DMA. On utilisera des caches possédant une capacité de 2 Koctets (lignes de 16 octets, 4 niveaux d'associativité, 32 sets).

B. Contrôleur DMA

Le composant PibusDma est capable d'adresser directement la mémoire (en lecture et en écriture), pour déplacer des données d'une zone de la mémoire vers une autre. Le coprocessseur DMA se comporte donc comme une cible, puisqu'il doit être configuré par le système d'exploitation pour démarrer le transfert, mais il se conduit également comme un maître, puisqu'il est capable d'initier des transactions sur le bus pour lire ou écrire en mémoire.

On aura donc deux maîtres pouvant travailler en parallèle dans cette architecture : le processeur MIPS32 et le coprocesseur DMA. Nous souhaitons analyser les mécanismes - matériels et logiciels - permettant la coopération entre les deux processus parallèles que sont le programme (logiciel) qui s'exécute sur le processeur, et l'automate (matériel) du coprocesseur DMA qui effectue le transfert. Le mécanisme général est le suivant :

  • Le logiciel système qui s'exécute sur le processeur MIPS32 configure le coprocesseur DMA et lance le transfert en écrivant dans différents registres du contrôleur DMA « mappés en mémoire » les paramètres du transfert qui sont: l'adresse de base du tampon source, l'adresse de base du tampon destination, et enfin le nombre de mots à transférer. Ceci fait, le programme qui a commandé le transfert continue son exécution.
  • Le coprocesseur DMA effectue le transfert en construisant des rafales de longueur fixe. Il exécute autant de paires de transactions que nécessaire: chaque paire est constituée par une lecture rafale d'un paquet dans le tampon source, suivie par une écriture rafale de ce paquet vers le tampon destination. La longueur de la rafale est définie par la capacité de stockage interne du coprocesseur DMA. On parle de coprocesseur, car le contrôleur DMA et le processeur travaillent en parallèle durant ce tranfert.
  • La durée du transfert est très variable, car elle dépend à la fois de la charge du bus et du nombre d'octets à transférer. Lorsque le transfert est terminé, le contrôleur DMA le signale au système d'explotation en activant une interruption. cette signalisation de fin de transfert est indispensable, pour permettre au programme ayant déclenché le transfert de re-utiliser les tampons mémoire concernés (source et destination).

Lisez la spécification fonctionnelle du composant PibusDma que vous trouverez dans l'en-tête du fichier pibus_dma.h pour répondre aux questions suivantes.

Question B1 : Quels sont les registres adressables du contrôleur DMA, et quel est l'effet d'une lectures ou d'une écriture dans chacun de ces registres ? Pourquoi l'adresse de base du segment associé au contrôleur DMA en tant que cible doit-elle être alignée sur une frontière de bloc de 32 octets ?

Question B2 : Quelle est la signification de l'argument burst du constructeur du composant PibusDma ?

Question B3 : Pourquoi faut-il deux automates (MASTER_FSM et TARGET_FSM) pour contrôler le coprocessseur DMA ?

Question B4 : Ce composant matériel contient évidemment d'autres registres que les 5 registres adressables. En analysant le modèle SystemC contenu dans le fichier pibus_dma.cpp , décrivez précisément la fonction de la bascule r_stop.

Question B5 : Complétez le graphe ci-dessous représentant la fonction de transition de l'automate MASTER_FSM du composant PibusDma. Attention, le graphe ci-dessous est incomplet.

  • Il faut ajouter deux transitions pour tenir compte du mécanisme de reset logiciel (écriture dans le registre RESET) : de l'état (READ_DT) vers l'état (IDLE), étiqueté "V", et de l'état (WRITE_DT) vers l'état (IDLE), étiqueté "W".
  • Il faut ajouter deux transitions pour tenir compte des rafales ne contenant qu'un seul mot: de l'état (READ_AD) vers l'état (READ_DT), étiqueté "X", et de l'état (WRITE_AD) vers l'état (WRITE_DT), étiqueté "Y".

Les signaux à utiliser en entrée de l'automate sont les suivants :

  • STOP: signal interne (bascule r_stop) indiquant l'absence de requête ou un reset logiciel
  • GNT: signal en provenance du bus indiquant que l'accès au bus autorisé
  • LAST: signal interne indiquant le dernier mot d'une requête de type burst
  • ACK: signal en provenance du bus indiquant si la requête a été prise en compte (valeurs possibles : READY, WAIT, ERROR)
  • END: signal interne indiquant qu'il s'agit de la dernière requête pour la copie demandée

C. Architecture matérielle

L'archive attachment:multi_tp7.tgz contient les fichiers dont vous aurez besoin. Créez un répertoire de travail tp7, et copiez les fichiers tp5_top.cpp, et tp5.desc dans ce répertoire. Décompressez l'archive. Vous trouverez comme d'habitude le logiciel embarqué dans le répertoire soft, que vous copierez dans tp7.

En analysant le code SystemC décrivant l'architecture générique (fichier tp5_top.cpp), répondez aux questions suivantes:

Question C1: Quelle est la longueur par défaut d'une rafale en nombre de mots de 32 bits) ? Quel est l'avantage d'utiliser des grosses rafales ? Quelle est la conséquence sur le matériel d'une augmentation de la longueur de la rafale ?

Question C2: Quelle est l'adresse de base du segment associé au périphérique DMA ? quel est son numéro de cible pour le composant BCU ? Le périphérique DMA étant aussi un maître sur le bus, il est connecté au composant BCU par les signaux REQ_DMA et GNT_DMA. Quel est son numéro de maître pour le BCU ? Sur quel port d'entrée du composant ICU est connecté la ligne d'interruption IRQ contrôlée par le DMA ?

D. Application logicielle

Placez-vous dans le répertoire soft.

Le programme défini dans le fichier main_dma.c est une extension du programme utilisé dans le TP5: il affiche successivement sur l'écran graphique une série d'images, qui sont des damiers dont le nombre de case varie d'une image à la suivante. A chaque itération, le programme construit donc une nouvelle image, qu'il stocke dans le tampon BUF avant d'utiliser l'appel système fb_sync_write() pour afficher cette image.

Question D1 : L'appel système fb_sync_write() n'utilise pas le coprocesseur DMA. Quel composant matériel effectue-t-il le transfert des pixels de l'image entre le tampon mémoire dans l'espace utilisateur et la mémoire video (frame buffer) ? Expliquez pour quoi cet appel système est bloquant. La réponse se trouve dans les fichier stdio.c et drivers.c.

Question D2 : Compilez et exécutez sur le prototype virtuel cette première application logicielle n'utilisant pas le contrôleur DMA. Quelle est la durée de construction d'une image (temps de remplissage du buffer) ? Quelle est la durée d'affichage ?

On utilise généralement le contrôleur DMA lorsqu'on a besoin de transférer de gros volumes de données, comme la copie d'une image d'un tampon mémoire (dans l'espace utilisateur) vers la mémoire graphique (située dans l'espace protégé réservé au système). On utilise les appels système fb_write() et fb_completed().

Question D3 : Quelle est la différence entre l'appel système fb_sync_write() et l'appel système fb_write() ? Quelle est l'utilité de l'appel système fb_completed() ?

Modifiez le programme contenu dans le fichier main_dma.c pour remplacer l'appel système fb_sync_write() par le couple fb_write() / fb_completed(). Vérifiez dans le fichier reset.s que l'ISR _isr_dma est bien initialisée dans le vecteur d'interruption, et que le registre de masque du composant ICU ne laisse passer que l'IRQ du DMA. Compilez, puis lancez l'exécution sur le prototype virtuel.

Question D4 : Quelle est la durée d'affichage d'une image avec le DMA ?

Puisqu'on a deux composants matériels capables de fonctionner en parallèle, il est tentant de paralléliser les phases de construction et d'affichage pour réduire encore le temps de traitement. On peut par exemple essayer de construire l'image (n+1) pendant qu'on affiche l'image (n).

Relancez l'exécution après avoir supprimé l'appel système fb_complete() dans le fichier main_dma.c, de façon à ne pas attendre la fin de l'affichage de l'image (n) pour commencer à construire l'image (n+1). Pour bien mettre en évidence le problème, il faut réduire la longueur des rafales du contrôleur DMA à un seul mot de 32 bits, pour ralentir volontairement l'affichage (en utilisant le paramètre DMABURST sur la ligne de commande du simulateur).

Question D5 : Quel défaut observez-vous sur le bord gauche de l'image affichée ? Expliquez précisément la cause de ce dysfonctionnement.

Pour synchroniser le programme utilisateur et le controleur DMA, on utilise la variable globale _dma_busy, qui est une variable globale du système d'exploitation, qui se comporte comme une bascule SET/RESET: elle est mise à 1 par le programme qui donne l'ordre d'affichage, et remise à 0 par le coprocesseur DMA lorsque le transfert est terminé.

Question D6 : Comment cette variable est-elle utilisée par les deux appels sytème fb_write() et fb_completed() ? Dans quelle fonction trouve-t-on le code de mise à 1 de la variable _dma_busy ? Dans quelle fonction trouve-t-on le code de mise à 0 ? Dans quel segment est stockée cette variable ?

E. Pipeline logiciel

Les difficultés analysées dans la section précédente sont liées aux accès concurrents au tampon BUF permettant la communication entre la tâche de construction exécutée par le processeur (producteur) et la tâche d'affichage exécutée par le coprocesseur DMA (consommateur).

Pour paralléliser ces deux tâches, il faut utiliser deux tampons BUF1 et BUF2 en bascule, permettant à la tâche productrice d'écrire dans le tampon BUF2, pendant que la tâche consommatrice lit dans le tampon BUF1, et vice-versa. Ceci permet de mettre en place un mécanisme de pipe-line logiciel comme décrit ci-dessous:

Période 1 Période 2 Période 3 Période 4 Période 5 Période 6
PROC Construit[1] Construit[2] Construit[3] Construit[4] Construit[5]
DMA Affiche[1] Affiche[2] Affiche[3] Affiche[4] Affiche[5]

Le fonctionnement général est le suivant :

  • Durant les périodes impaires (2i + 1) :
    1. Construction de l'image (2i + 1) dans BUF1
    2. Affichage de l'image (2i) stockée dans BUF2 (si i > 0)
  • Durant les périodes paires (2i) :
    1. Construction de l'image (2i) dans BUF2, (si i < 3)
    2. Affichage de l'image (2i - 1) stockée dans BUF1

Grâce à l'utilisation alternative des tampons mémoires pairs et impairs, à aucun moment on ne lit et on n'écrit simultanément dans le même tampon.

Re-écrivez un programme main_pipe.c qui réalise le pipeline logiciel ci-dessus. Ce programme devra être organisé en trois phases:

  • chargement initial du pipe-line, appelée prologue (période 0)
  • traversée du pipeline (periodes 1, 2, 3, 4)
  • vidage du pipeline, appelée épilogue (période 5)

Question E1: Il faut synchroniser le pipeline. Quelle condition doit être testées par le logiciel pour passer de la période (n) à la période (n + 1) ?

Question E2: Quel est le gain (en nombre de cycles) apporté par le parallélisme pipeline, par rapport a une execution séquentielle ? Comment interprétez-vous ce résultat ?

F. Traitement des erreurs

On s'intéresse maintenant au traitement et à la signalisation des erreurs.

Le contrôleur DMA est un maître capable d'adresser directement la mémoire (en lecture et en écriture), mais ce maître ne prend aucune initiative. Il ne fait qu'exécuter les transfert qui ont été définis par un programme utilisateur, et le programmeur peut faire des erreurs sur la valeur des adresses des tampons source ou destination.

Question F1 : Pourquoi le système d'exploitation interdit-il que l'adresse du tampon source (dans le cas de l'appel système fb_write()) ou l'adresse du tampon destination (dans le cas de l'appel système fb_read()) appartienne à la zone protégée de l'espace adressable ? Pourquoi ce type d'erreur doit-il absolument être détecté avant que le contrôleur DMA commence à effectuer le transfert ?

Une autre cause d'erreur est l'utilisation d'adresses qui ne correspondent à aucun segment défini. Cette erreur est détectée au moment où le contrôleur DMA effectue le transfert, et reçoit de la part du contrôleur mémoire une réponse de type bus error, en réponse à sa commande de lecture ou d'écriture. Un processeur programmable tel que le MIPS32 qui reçoit une réponse bus error se branche au gestionnaire d'exception pour signaler l'erreur et permettre le debug, mais le contrôleur DMA est un automate cablé qui n'a évidemment pas de gestionnaire d'exception logiciel...

Question F2 : Quel est le mécanisme qui permet au contrôleur DMA de signaler ce type erreur au programme utilisateur ? Pour répondre à cette question, il faut analyser toute la chaîne de signalisation :

  • comportement du contrôleur DMA qui reçoit une réponse bus error : dans le fichier pibus_dma.cpp
  • code de la routine d'interruption _isr_dma associée au DMA : dans le fichier irq_handler.c
  • code de la fonction système _fb_completed() : dans le fichier drivers.c

Pour tester ces mécanismes de signalisation d'erreur, modifiez le programme contenu dans le fichier main_dma.c pour introduire volontairement une erreur sur l'adresse du buffer passée en argument à l'appel système fb_write().

Question F3 : Quel appel système signale l'erreur si l'adresse erronée est non définie (par exemple adresse 0x0, qui ne correspond à aucun segment défini) ? Quel appel système signale l'erreur si l'adresse erronée appartient à la zone protégée (par exemple adresse 0x80000000) ?

Ne soyez pas paresseux. Prenez le temps d'analyser le code en détail, car cette partie sur la signalisation d'erreur est la plus importante du TP...

G. Amélioration du parallélisme

Dans un pipeline logiciel, le gain apporté par la parallélisation entre plusieurs tâches est faible dans le cas où une seule tâche a une durée beaucoup plus grande que les autres, car le pipe-line n'est pas "équilibré". Dans ce TP, c'est la tâche de construction de l'image qui est beaucoup plus longue que la tâche d'affichage. Pour améliorer les performances, il faut donc découper la tâche logicielle de construction d l'images en partageant le travail entre plusieurs tâches logicielles s'exécutant en parallèle sur plusieurs coeurs. C'est le but de cette dernière partie.

On vise donc la réalisation d'un pipe-line où une tâche matérielle et quatre tâches logicielles s'exécutent en parallèle suivant le chronogramme suivant:

Période 1 Période 2 Période 3 Période 4 Période 5 Période 6
PROC_0 Construit[1] Construit[2] Construit[3] Construit[4] Construit[5]
PROC_1 Construit[1] Construit[2] Construit[3] Construit[4] Construit[5]
PROC_2 Construit[1] Construit[2] Construit[3] Construit[4] Construit[5]
PROC_3 Construit[1] Construit[2] Construit[3] Construit[4] Construit[5]
DMA Affiche[1] Affiche[2] Affiche[3] Affiche[4] Affiche[5]

Pour ce qui concerne la synchronisation, on a maintenant besoin d'une barrière entre 5 tâches au lieu de 2. Ceci peut être réalisé en chargeant une seule tâche logicielle de se synchroniser avec la tâche matérielle DMA au moyen des primitives fb_write() et fb_completed(), et en ajoutant une barrière de synchronisation entre les quatre tâches logicielles.

Question G1 Modifiez l'architecture matérielle pour disposer de 4 processeurs. Modifiez le programme de construction d'image pour partager le travail entre 4 tâches en vous inspirant de ce que vous avez fait dans le TP5. Il faut également modifier le code de reset pour lancer les quatre applications logicielles sur les quatre processeurs.

H. Compte-rendu

Les réponses aux questions ci-dessus doivent être rédigées sous éditeur de texte et ce compte-rendu doit être rendu au début de la séance de TP suivante. De même, le simulateur, fera l'objet d'un contrôle (par binôme) au début de la séance de TP de la semaine suivante.

Last modified 8 months ago Last modified on Mar 15, 2024, 3:10:55 PM

Attachments (4)

Download all attachments as: .zip