Fonctionnement d'un ordinateur/Contrôleur mémoire externe

Un livre de Wikilivres.
Sauter à la navigation Sauter à la recherche

Pour interfacer le processeur à la mémoire, on utilise un circuit spécialisé : le contrôleur mémoire externe. Celui-ci est placé sur la carte mère ou dans le processeur, et ne doit pas être confondu avec le contrôleur mémoire intégré dans la mémoire. Ce contrôleur mémoire externe gère :

  • l'entrelacement ;
  • le rafraîchissement mémoire ;
  • le séquencement des accès mémoires ;
  • la traduction des accès mémoires en suite de commandes (ACT, sélection de ligne, etc.) ;
  • l’interfaçage électrique.

Architecture du contrôleur[modifier | modifier le wikicode]

Ce contrôleur mémoire externe est schématiquement composé de quatre modules séparés. Le module d'interface avec le processeur gère l'entrelacement. Le module d’ordonnancement des commandes contrôle le rafraîchissement et le séquencement des accès mémoires (dans le cas où ils ne sont pas envoyés dans l'ordre à la mémoire). Ce module contient notamment des FIFO pour mettre en attente les accès mémoires, un module de rafraichissement, ainsi qu'un circuit d'arbitrage (qui décide quelle requête envoyer à la mémoire). Le module de décodage des commandes traduit les accès mémoires en une suite de commandes ACT, READ, PRECHARGE, etc. C'est ce module qui tient compte des délais mémoires et gère l'envoi des commandes au cycle près. Le module d'interface mémoire sert quand la mémoire et le processeur n'utilisent pas les mêmes tensions pour coder un bit : ce module se charge de la conversion de tension. Il prend aussi en charge la détection et la correction des erreurs.

Module d'interface avec la mémoire.

Si la mémoire (et donc le contrôleur) est partagée entre plusieurs processeurs, le module d'interface hôte est dupliqué en autant d’exemplaires qu'il y a de processeurs. Le module de commande contient un circuit pour que les processeurs ne se marchent pas sur les pieds pour l'accès à la mémoire. Ce circuit fait en sorte que chaque processeur ait sa part, et puisse accéder à la mémoire sans trop d'attente : cela évite qu'un processeur monopolise la mémoire pour lui tout seul.

Politique de gestion du row buffer[modifier | modifier le wikicode]

Le contrôleur mémoire décide quand envoyer les commandes PRECHARGE, qui pré-chargent les bitlines et vident le row buffer. Il peut gérer cet envoi des commandes PRECHARGE de diverses manières nommées respectivement politique de la page fermée, politique de la page ouverte et politique hybride.

Politique de la page fermée[modifier | modifier le wikicode]

Dans le premier cas, le contrôleur ferme systématiquement toute ligne ouverte par un accès mémoire : chaque accès est suivi d'une commande PRECHARGE. Cette méthode est adaptée à des accès aléatoires, mais est peu performante pour les accès à des adresses consécutives. On appelle cette méthode la close page autoprecharge, ou encore politique de la page fermée.

Politique de la page ouverte[modifier | modifier le wikicode]

Avec des accès consécutifs, les données ont de fortes chances d'être placées sur la même ligne. En conséquence, fermer celle-ci pour la réactiver au cycle suivant est contreproductif : il vaut mieux garder la ligne active et ne la fermer que lors d'un accès à une autre ligne. Cette politique porte le nom d'open page autoprecharge, ou encore politique de la page ouverte. Lors d'un accès, la commande à envoyer peut faire face à deux situations : soit la nouvelle requête accède à la ligne ouverte, soit elle accède à une autre ligne. Dans le premier cas, on doit juste changer de colonne : c'est un row buffer hit. Le temps nécessaire pour accéder à la donnée est donc égal au temps nécessaire pour sélectionner une colonne avec une commande READ, WRITE, WRITA, READA : on observe donc un gain signifiant comparé à la politique de la page fermée. Dans le second cas, c'est un row buffer miss et il faut procéder comme avec la politique de la page fermée, à savoir vider le row buffer avec une commande PRECHARGE, sélectionner la ligne avec une commande ACT, avant de sélectionner la colonne avec une commande READ, WRITE, WRITA, READA. Détecter un row buffer miss ou un row buffer hit n'est pas très compliqué. Le contrôleur a juste à se souvenir des lignes et banques actives avec une petite mémoire : la table des banques. Pour détecter un hit ou un miss, le contrôleur doit simplement extraire la ligne de l'adresse à lire ou écrire, et vérifier si celle-ci est ouverte : si c'est le cas, c'est un hit, un miss sinon.

Le contrôleur mémoire peut optimiser l'utilisation de la politique de la page ouverte en changeant l'ordre des requêtes mémoires pour regrouper les accès à la même ligne/banque. Une première solution consiste à mettre en attente les écritures et effectuer les lectures en priorité. Il suffit d'utiliser des files d'attente séparées pour les lectures et écritures. Si une lecture accède à une donnée qui n'a pas encore été écrite dans la mémoire (car mise en attente), la donnée est lue directement dans la file d'attente des écritures. Cela demande de comparer toute adresse à lire avec celles des écritures en attente : la file d'attente est donc une mémoire associative.

Double file d'attente pour les lectures et écritures.

Une autre solution répartit les accès mémoire sur plusieurs banques en parallèle. Ainsi, on commence par servir la première requête de la banque 0, puis la première requête de la banque 1, et ainsi de suite. Cela demande de trier les requêtes de lecture ou d'écriture suivant la banque de destination : on se retrouve avec une file d'attente pour chaque banque.

Gestion parallèle des banques.

Une autre solution consiste à regrouper plusieurs accès à des données successives en un seul accès en rafale.

Politiques dynamiques[modifier | modifier le wikicode]

Pour gagner en performances et diminuer la consommation énergétique de la mémoire, il existe des techniques hybrides qui alternent entre la politique de la page fermée et la politique de la page ouverte en fonction des besoins. La plus simple décide s'il faut maintenir ouverte une ligne accédée récemment. Il suffit de regarder si les accès mémoires mis en attente vont accéder à la page : la ligne est laissée ouverte si au moins un accès en attente y accède. Une autre politique laisse la ligne ouverte, sauf si un accès en attente accède à une ligne différente de la même banque. Avec l'algorithme FR-FCFS (First Ready, First-Come First-Service), les accès mémoires qui accèdent à une ligne ouverte sont exécutés en priorité, et les autres sont mis en attente. Dans le cas où aucun accès mémoire ne lit une ligne ouverte, le contrôleur prend l'accès le plus ancien, celui qui attend depuis le plus longtemps comparé aux autres. Pour implémenter ces techniques, le contrôleur compare la ligne ouverte dans le row buffer et les lignes des accès en attente. Ces techniques demandent de mémoriser la ligne ouverte, pour chaque banque, dans une mémoire RAM : la bank status memory. Le contrôleur extrait les numéros de banque et de ligne des accès en attente pour adresser la bank status memory, le résultat étant comparé avec le numéro de ligne de l'accès.

Architecture d'un module de gestion des commandes à politique dynamique.

Politiques prédictives[modifier | modifier le wikicode]

Certaines techniques prédisent s'ils faut fermer ou laisser ouvertes les pages ouvertes. La méthode la plus simple consiste à laisser ouverte chaque ligne durant un temps prédéterminé avant de la fermer. Une autre solution consiste à effectuer ou non la pré-charge en fonction du type d'accès mémoire effectué par le dernier accès : on peut très bien décider de laisser la ligne ouverte si l'accès mémoire précédent était une rafale, et fermer sinon. Une autre solution consiste à mémoriser les N derniers accès et en déduire s'il faut fermer ou non la prochaine ligne. On peut mémoriser si l'accès en question a causé la fermeture d'une ligne avec un bit : mémoriser les N derniers accès demande d'utiliser un simple registre à décalage, un registre couplé à un décaleur par 1. Pour chaque valeur de ce registre, il faut prédire si le prochain accès demandera une ouverture ou une fermeture. Une première solution consiste à faire la moyenne des bits à 1 dans ce registre : si plus de la moitié des bits est à 1, on laisse la ligne ouverte et on ferme sinon. Pour améliorer l'algorithme, on peut faire en sorte que les bits des accès mémoires les plus récents aient plus de poids dans le calcul de la moyenne. Mais rien de transcendant. Une autre technique consiste à détecter les cycles d'ouverture et de fermeture de page potentiels. Pour cela, le contrôleur mémoire associe un compteur pour chaque valeur du registre. En cas de fermeture du row buffer, ce compteur est décrémenté, alors qu'une non-fermeture va l'incrémenter : suivant la valeur de ce compteur, on sait si l'accès a plus de chance de fermer une page ou non.