Dans les micro-architectures modernes avec registre renommant le coût de mise en œuvre des drapeaux ou non, les drapeaux sont assez similaires. La principale différence à laquelle je peux penser est que certains indicateurs indiquent les caractéristiques d'une valeur (la valeur est-elle négative? La valeur est-elle nulle? La valeur a-t-elle une parité paire ou impaire?), Tandis que d'autres représentent un événement qui s'est produit lors d'une opération précédente (l'instruction add a-t-elle eu une exécution ou un débordement?) Cela a conduit à une situation moins qu'idéale sur le MIPS lorsque vous vouliez simuler un ajout 64 bits sur l'architecture 32 bits (ou un ajout 128 bits sur le Architecture 64 bits.) Sur la plupart des architectures avec un indicateur de portage, il existe unadd-with-carry
, qui comprend le drapeau de report de l'instruction d'ajout précédente. Cela rend la simulation de l'arithmétique multi-précision relativement peu coûteuse sur de nombreuses architectures avec des registres de drapeaux.
D'un autre côté, tester un registre à N bits pour zéro ou non nul est en fait étonnamment cher. Pour tester un registre à N bits sur zéro, vous devez effectuer une opération NOR à N bits, qui nécessite des niveaux logiques pour le calcul. Sur les architectures avec des drapeaux, la logique supplémentaire pour le calcul zéro / non nul à la fin de l'étape ALU peut ralentir le temps (ou forcer l'ALU à avoir deux opérations de cycle). Pour cette raison, je pense que certains les architectures, comme SPARC, avaient deux versions de chaque opération arithmétique, une qui définissait des indicateurs et une qui ne le faisait pas.O ( logN)
Mais MIPS n'enregistre rien ici. Ils ont simplement déplacé le problème ailleurs. Sur MIPS, il y a une branch-on-equal
instruction. Cela signifie que l'instruction de branchement doit en fait avoir un étage ALU (y compris quelque chose comme une xor
opération au niveau du bit suivie d'un nor
pour réduire au bit unique égal / non égal) avant de déterminer dans quelle direction va la branche.
L'architecture DEC Alpha a tenté de diviser la différence en utilisant une astuce. DEC Alpha n'avait aucun registre de drapeaux, mais n'avait pas non plus d' branch-on-equal
instruction. Au lieu de cela, les instructions de branche regardent toutes l'état d'un seul registre à usage général. Il est branch-on-zero
, branch-on-not-zero
, branch-on-less-than-zero
, etc. L'astuce est que vous pouvez donner à chaque registre banalisé un peu de 65e supplémentaire qui vous indique si les autres 64 bits sont tous nuls ou non. Cela ressemble plus à un registre de drapeaux: toutes les instructions de branchement regardent un seul bit (qui est déjà calculé) pour prendre leur décision, mais maintenant vous êtes de retour pour trouver comment calculer ce bit indicateur de zéro supplémentaire pendant une ALU normale cycle. (Et vous ne pouvez toujours pas faire de l'arithmétique multi-précision simplement en regardant l'indicateur de report de l'opération précédente.)
Logique errante
la source
1 Du point de vue ISA
Avoir des instructions de test qui ne définissent que les drapeaux n'est qu'un moyen de réduire la pression de registre dans les architectures de registre affamées. Si vous avez suffisamment de registres, modifiez simplement l'un d'entre eux et ignorez le résultat. L'astuce d'avoir un registre 0 avec une valeur d'entrée 0 est juste une astuce de codage pratique lorsque vous avez suffisamment de registres que la fixation de l'un d'entre eux à 0 est préférable à l'augmentation du nombre d'instructions. Il est alors pratique de l'utiliser également comme cible (cela réduit le nombre de fausses dépendances).
Encodage à nouveau. Si vous encodez la condition en sauts, vous aurez des sauts avec 3 opérandes (les deux à comparer et la cible de saut), dont deux vous aimeriez être des valeurs immédiates, un que vous aimeriez être aussi grand que possible (les sauts ont souvent leur propre format de codage afin que la cible puisse utiliser autant de bits que possible). Ou vous laissez tomber les possibilités.
L'utilisation de drapeaux vous donne plus d'occasions de les définir. Ce ne sont pas seulement les opérations de comparaison qui peuvent définir les indicateurs, mais tout ce que vous voulez. (Avec la mise en garde que plus vous avez d'opérations qui définissent des indicateurs, plus vous devez vous assurer que la dernière opération qui a défini les indicateurs est celle que vous voulez). Si vous avez des drapeaux, vous pouvez tester le nombre de conditions (souvent 16) multiplié par le nombre d'instructions qui sont en mesure de définir les drapeaux (si vous n'utilisez pas de drapeaux, vous vous retrouvez avec autant de sauts conditionnels que vous avoir des choses à tester ou il y a des choses que vous ne permettez pas de tester aussi facilement (transporter ou déborder par exemple).
2 Du point de vue du réalisateur
Le test des drapeaux est facile et peut être fait rapidement. Plus votre test est complexe, plus il aura d'effet sur la durée du cycle (ou la structure du pipeline si vous êtes pipeliné). Cela est particulièrement vrai pour les implémentations plus simples, lorsque vous arrivez à un processeur haut de gamme utilisant toutes les astuces du livre, l'effet est assez minime.
Avoir des drapeaux signifie que beaucoup d'instructions ont plusieurs résultats (le résultat naturel et chacun des drapeaux modifiés). Et à partir d'un PDV de micro-architecture, plusieurs résultats sont mauvais (vous devez garder une trace de leur association). Lorsque vous n'avez qu'un seul ensemble d'indicateurs, qui introduisent des dépendances (inutiles si l'indicateur n'est pas utilisé ensuite), vous devez gérer d'une manière ou d'une autre. Encore une fois, cela est particulièrement vrai pour les implémentations plus simples, lorsque vous arrivez à un processeur haut de gamme en utilisant toutes les astuces du livre, les difficultés supplémentaires sont éclipsées par le reste du processeur.
la source
Sur une machine 32 bits, une instruction "ajouter avec porter" utilisée dans le cadre d'une séquence d'addition multi-précision doit accepter une valeur d'opérandes de 65 bits et calculer une somme de 33 bits. Les spécifications du registre source identifieront d'où les 64 bits d'opérande devraient provenir, et la spécification du registre de destination dira où les 32 bits inférieurs du résultat devraient aller, mais que faire de l'opérande "ajouter un supplémentaire" ou du bit supérieur du résultat? Être autorisé à spécifier dans le cadre de l'instruction d'où l'opérande supplémentaire devrait provenir et où le bit de résultat supplémentaire devrait aller serait modérément utile, mais il ne serait généralement pas assez utile pour justifier un champ supplémentaire dans l'opcode. Avoir un «emplacement» fixe pour gérer le drapeau de transport peut être un peu gênant du point de vue de la programmation des instructions, mais c'est
Si l'on essayait de concevoir un jeu d'instructions pour permettre l'arithmétique multi-précision mais que chaque instruction était limitée à deux opérandes 32 bits et un opérande de destination 32 bits, on pourrait implémenter un "add" 64 bits dans quatre instructions: "set r5 à 1 si r0 + r2 porterait ou zéro sinon; calculer r4 = r1 + r3; calculer r5 = r4 + r5; calculer r4 = r0 + r2 ", mais pour aller au-delà, il faudrait trois instructions pour chaque mot supplémentaire. Avoir un indicateur de portage disponible comme source et destination supplémentaire réduit le coût à une instruction par mot.
Notez, btw, que le fait d'avoir un bit d'instruction contrôlant si l'instruction met à jour le registre d'indicateur peut faciliter l'exécution dans le désordre, car les instructions qui utilisent ou modifient les bits d'indicateur doivent conserver leur séquence les unes par rapport aux autres, mais les instructions qui ne le font pas non plus peuvent être réarrangé librement. Étant donné la séquence:
une unité d'exécution pourrait assez facilement reconnaître que la troisième instruction pourrait s'exécuter sans avoir à attendre que les données soient lues
[r1]
, mais si la deuxième instruction l'avait été,adds r0,r0,r2
cela ne serait possible que si l'unité d'exécution pouvait s'assurer qu'au moment où quelque chose essayait d'utiliser les drapeaux, le drapeau zéro contiendrait la valeur établie dans la troisième instruction mais le drapeau de retenue conserverait la valeur dans la seconde.la source
Réponse simple ... opération de mémoire rapide et bon marché qui ne nécessite absolument aucune utilisation de bus interne, sauf l'instruction elle-même. Il peut être utilisé comme une pile booléenne sans pile ni bit de processus, sans mémoire.
la source