Ce projet était mon projet final pour EECS : 2021. C'était un projet de pipeline RISC-V où l'objectif était d'apprendre à optimiser le code. Ce projet m'a aidé à exceller dans le cours, acquérant une très bonne compréhension pour me préparer à l'examen et obtenant une note de 100%
Détails de l'attribution
Contexte :
Un processeur statiquement planifié à deux problèmes bénéficie du compilateur pour regrouper deux instructions dans un "paquet de problème" à exécuter en un cycle d'horloge. Ceci est en contraste avec une instruction à problème unique qui ne peut exécuter qu'une instruction en un seul cycle. Le paquet de problème est parfois appelé un mot d'instruction très long (VLIW). Le compilateur vise à éliminer tous les risques en réordonnant les instructions dans des paquets de problème. Parfois, le compilateur doit remplir un VLIW avec une instruction de non-opération (par exemple, NOP) si nécessaire. Le compilateur doit regrouper une instruction ALU/branchement avec une instruction de chargement/stockage ; s'il ne peut pas le faire, il doit utiliser NOP pour remplir l'instruction inutilisée.
Spécifications :
Compte tenu du contexte ci-dessus et du code suivant :
for(int i=0; i!=j; i=i+2) b[i]=a[i]–a[i+1];
Nous voulons comparer les performances des processeurs à problème unique et à problème multiple, en tenant compte des transformations de programme qui peuvent être effectuées pour optimiser l'exécution à 2 problèmes.
Un compilateur effectuant peu ou pas d'optimisation pourrait produire le code d'assemblage RISC-V suivant :
Comme vu ci-dessus, nous pouvons supposer que i est x12, j est x13, a est x10, b est x11, et x5, x6, x7, x29, x30, et x31 sont des registres temporaires.
Notre processeur statiquement planifié à deux problèmes a les propriétés suivantes :
Une instruction doit être une opération mémoire ; l'autre doit être une instruction arithmétique/logique ou un branchement.
Le processeur a toutes les voies de renvoi possibles entre les étapes (y compris les voies menant à l'étape ID pour la résolution de branchement).
Le processeur a une prédiction de branchement parfaite.
Deux instructions ne peuvent pas être émises ensemble dans un paquet si l'une dépend de l'autre.
Si un arrêt est nécessaire, les deux instructions dans le paquet de problème doivent s'arrêter.
Questions
Partie A :
Dessinez un schéma de pipeline montrant comment le code RISC-V donné ci-dessus s'exécute sur le processeur à deux problèmes. Supposons que la boucle se termine après deux itérations.
Partie B :
Quel est l'accélération du passage d'un processeur à problème unique à un processeur à deux problèmes? (Supposons que la boucle s'exécute 100 000 itérations).
Partie C :
Réorganiser/rewriter le code RISC-V donné ci-dessus pour obtenir de meilleures performances sur le processeur à problème unique. Astuce : Utilisez l'instruction “beqz x13,DONE” pour sauter complètement la boucle si j = 0.
Partie D :
Réorganiser/rewriter le code RISC-V donné ci-dessus pour obtenir de meilleures performances sur le processeur à deux problèmes. (N'unwroll la boucle, cependant.)
Partie E :
Répétez la Partie A, mais cette fois utilisez votre code optimisé de la Partie D.
Partie F :
Quelle est l'accélération du passage d'un processeur à problème unique à un processeur à deux problèmes lors de l'exécution du code optimisé des Partie C et D?
Partie G :
Déroulez le code RISC-V de la Partie D de manière à ce que chaque itération de la boucle déroulée gère deux itérations de la boucle d'origine. Ensuite, réorganisez/rewritez votre code déroulé pour obtenir de meilleures performances sur le processeur à deux problèmes. Vous pouvez supposer que j est un multiple de 4. Astuce : vous voudrez peut-être réorganiser la boucle pour que certains calculs apparaissent à l'extérieur et à la fin de la boucle. Vous pouvez également supposer que les valeurs dans les registres temporaires ne sont pas nécessaires après la boucle.
Partie H :
Quelle est l'accélération du passage d'un processeur à problème unique à un processeur à deux problèmes lors de l'exécution du code déroulé optimisé que vous avez créé dans la Partie G, en supposant que le processeur à deux problèmes peut exécuter deux instructions arithmétiques/logiques ensemble (par exemple, la première instruction dans un paquet peut être n'importe quel type d'instruction, mais la seconde doit être une instruction arithmétique ou logique. Et notez que deux opérations mémoire ne peuvent pas être planifiées en même temps.)
Partie I :
L'implémentation d'un processeur superscalaire faciliterait-elle l'atteinte de vitesses de traitement plus rapides (par rapport aux scénarios mentionnés précédemment) tout en maintenant les mêmes configurations d'horloge CPU? Si la réponse est affirmative, veuillez expliquer votre conception, en incorporant les composants utilisés, de manière analogue à notre approche avec les pipelines RISC-V. En revanche, si votre réponse est négative, veuillez expliciter la raison de votre assertion.