Je lisais sur Arduino et l'architecture AVR et je suis resté bloqué au point que la façon dont le pipeline se bloque ou bouillonne est résolue par l'introduction de l'architecture Harvard dans l'AVR. permet de charger un programme sans opérateur.Mais comment cela aide-t-il à résoudre le problème ci-dessus?
12
Réponses:
L'architecture Harvard, qui a d'ailleurs été utilisée bien avant l'invention des AVR, a en effet des espaces d'adressage séparés pour la mémoire du programme et pour la mémoire des données. Ce que cela apporte à la partie, c'est la possibilité de concevoir le circuit de manière à ce qu'un bus et un circuit de commande séparés puissent être utilisés pour gérer le flux d'informations de la mémoire de programme et le flux d'informations vers la mémoire de données. L'utilisation des bus séparés signifie que la récupération et l'exécution du programme peuvent se poursuivre sans interruption d'un transfert occasionnel de données vers la mémoire de données. Par exemple, dans la version la plus simple de l'architecture, l'unité de récupération de programme peut être occupée à récupérer l'instruction suivante dans la séquence de programme en parallèle avec l'opération de transfert de données qui peut avoir fait partie de l'instruction de programme précédente.
À ce niveau le plus simple, l'architecture Harvard a une limitation en ce qu'il n'est généralement pas possible de mettre du code de programme dans la mémoire de données et de l'exécuter à partir de là.
Il existe de nombreuses variantes et complexités qui peuvent être ajoutées en plus de cette forme la plus simple de l'architecture que j'ai décrite. Un ajout courant consiste à ajouter une mise en cache d'instructions au bus d'informations de programme qui permet à l'unité d'exécution d'instructions d'accéder plus rapidement à l'étape de programme suivante sans avoir à passer à une mémoire plus lente pour récupérer l'étape de programme chaque fois qu'elle est requise.
la source
Quelques notes en plus de la réponse de Michaels:
1) l'architecture Harvard n'exige pas qu'il y ait deux espaces séparés pour les données et le code, juste qu'ils sont (principalement) récupérés sur deux bus différents .
2) le problème résolu par l'architecture Harvard est le conflit de bus: pour un système où la mémoire de code peut à peu près fournir les instructions assez rapidement pour que le processeur fonctionne à pleine vitesse, la charge supplémentaire des récupérations / stockages de données ralentira le processeur vers le bas. Ce problème est résolu par une architecture Hardvard: une mémoire (un peu) trop lente pour la vitesse du CPU.
Notez que la mise en cache est une autre façon de résoudre ce problème. Souvent, la récupération et la mise en cache sont utilisées dans des combinaisons intéressantes.
Harvard utilise deux bus. Il n'y a aucune raison inhérente de s'en tenir à deux, dans des cas très particuliers, plus de deux sont utilisés, principalement dans les DSP (processeurs de signaux numériques).
La banque de mémoire (dans le sens de distribuer des accès à la mémoire à différents ensembles de puces) peut être considérée comme une sorte de récupération à l'intérieur du système de mémoire lui-même, non pas sur la base de la distinction données / code, mais sur certains bits de l'adresse.
la source
Une architecture Harvard pure permettra généralement à un ordinateur avec un niveau de complexité donné de fonctionner plus rapidement qu'une architecture Von Neuman, à condition qu'aucune ressource ne soit partagée entre le code et les mémoires de données. Si des limitations de brochage ou d'autres facteurs obligent l'utilisation d'un bus pour accéder aux deux espaces mémoire, ces avantages sont susceptibles d'être largement annulés.
Une architecture Harvard "pure" sera limitée à l'exécution de code qui est mis en mémoire par un mécanisme autre que le processeur qui exécutera le code. Cela limite l'utilité de telles architectures pour les appareils dont le but n'est pas défini par l'usine (ou quelqu'un avec un équipement de programmation spécialisé). Deux approches peuvent être utilisées pour atténuer ce problème:
Certains systèmes ont des zones de code et de mémoire distinctes, mais fournissent un matériel spécial auquel il peut être demandé de reprendre brièvement le bus de code, d'effectuer une opération et de retourner le contrôle à la CPU une fois cette opération terminée. Certains de ces systèmes nécessitent un protocole assez élaboré pour effectuer de telles opérations, certains ont des instructions spéciales pour effectuer une telle tâche, et certains surveillent même certaines adresses de "mémoire de données" et déclenchent la prise de contrôle / libération lorsqu'une tentative est faite pour y accéder . Un aspect clé de ces systèmes est qu'il existe des zones de mémoire explicitement définies pour le "code" et les "données"; même s'il est possible pour le CPU de lire et d'écrire l'espace "code", il est toujours reconnu comme étant sémantiquement différent de l'espace de données. '
Une approche alternative qui est utilisée dans certains systèmes haut de gamme consiste à avoir un contrôleur avec deux bus mémoire, un pour le code et un pour les données, tous deux connectés à une unité d'arbitrage de mémoire. Cette unité est à son tour connectée à divers sous-systèmes de mémoire à l'aide d'un bus de mémoire distinct pour chacun. Un accès par code à un sous-système de mémoire peut être traité simultanément avec un accès aux données à un autre; ce n'est que si le code et les données tentent d'accéder simultanément au même sous-système que l'un ou l'autre devra attendre.
Sur les systèmes qui utilisent cette approche, les parties non critiques des performances d'un programme peuvent simplement ignorer les frontières entre les sous-systèmes de mémoire. Si le code et les données se trouvent dans le même sous-système de mémoire, les choses ne fonctionneront pas aussi vite que si elles se trouvaient dans des sous-systèmes séparés, mais pour de nombreuses parties d'un programme typique, cela n'aura pas d'importance. Dans un système typique, il y aura une petite partie du code où les performances comptent vraiment, et il ne fonctionnera que sur une petite partie des données détenues par le système. Si l'on avait un système avec 16 Ko de RAM divisé en deux partitions de 8 Ko, on pourrait utiliser des instructions de l'éditeur de liens pour s'assurer que le code critique pour les performances se trouvait près du début de l'espace mémoire global et que les données critiques pour les performances étaient proches de la fin. Si la taille globale du code atteint par exemple 9K, le code dans le dernier 1K s'exécuterait plus lentement que le code placé ailleurs, mais ce code ne serait pas critique en termes de performances. De même, si le code n'était par exemple que de 6 Ko, mais que les données atteignaient 9 Ko, l'accès au 1 Ko de données le plus bas serait lent, mais si les données essentielles aux performances étaient situées ailleurs, cela ne poserait pas de problème.
Notez que si les performances seraient optimales si le code était inférieur à 8K et les données inférieures à 8K, la conception du système de mémoire susmentionnée n'imposerait aucune partition stricte entre le code et l'espace de données. Si un programme n'a besoin que de 1K de données, le code peut atteindre 15K. Si elle n'a besoin que de 2 Ko de code, les données pourraient atteindre 14 Ko. Beaucoup plus polyvalent que d'avoir une zone 8K juste pour le code et une zone 8K juste pour les données.
la source
Un aspect qui n'a pas été discuté est que pour les petits microcontrôleurs, généralement avec seulement un bus d'adresse 16 bits, une architecture Harvard double effectivement (ou triple) l'espace d'adressage. Vous pouvez avoir 64 Ko de code, 64 Ko de RAM et 64 Ko d'E / S mappées en mémoire (si le système utilise des E / S mappées en mémoire au lieu de numéros de port, ces derniers séparant déjà l'adressage d'E / S du code et Espaces RAM).
Sinon, vous devez entasser le code, la RAM et éventuellement l'adresse d'E / S dans le même espace d'adressage de 64 Ko.
la source