Je lisais la réponse populaire sur Branch Prediction de https://stackoverflow.com/q/11227809/555690 , et il y a quelque chose qui me déroute:
- Si vous avez bien deviné, cela continue.
- Si vous vous trompez, le capitaine s'arrête, recule et vous crie dessus pour actionner l'interrupteur. Ensuite, il peut redémarrer sur l'autre chemin.
Si vous devinez à chaque fois, le train n'aura jamais à s'arrêter.
Si vous vous trompez trop souvent, le train passera beaucoup de temps à s'arrêter, à reculer et à redémarrer.
Mais c'est ce que je ne comprends pas: pour savoir si votre supposition était bonne ou mauvaise, vous devez quand même vérifier l'état . Alors, comment fonctionne la prédiction de branche, si vous effectuez toujours la même vérification conditionnelle?
Ce que j'essaie de dire, c'est que la prédiction de branche n'est pas exactement la même chose que de ne pas avoir de prédiction de branche du tout parce que vous effectuez les mêmes vérifications conditionnelles de toute façon? (évidemment je me trompe, mais je ne comprends pas)
la source
Réponses:
Bien sûr, l'état est vérifié à chaque fois. Mais au moment où il est vérifié, il est loin dans le pipeline du processeur. Entre-temps, d'autres instructions sont également entrées dans le pipeline et sont à divers stades d'exécution.
Habituellement, une condition est immédiatement suivie d'une instruction de branchement conditionnel, qui se branche si la condition est évaluée à VRAI, ou échoue si la condition est évaluée à FAUX. Cela signifie qu'il existe deux flux d'instructions différents qui peuvent être chargés dans le pipeline après l'instruction de condition et l'instruction de branchement, selon que la condition est évaluée à VRAI ou FAUX. Malheureusement, immédiatement après le chargement de l'instruction de condition et de l'instruction de branchement, le processeur ne sait pas encore à quoi la condition va être évaluée, mais il doit toujours continuer à charger des éléments dans le pipeline. Il choisit donc l'un des deux ensembles d'instructions en fonction d'une supposition quant à la condition à laquelle la condition sera évaluée.
Plus tard, alors que l'instruction de condition remonte le pipeline, il est temps de l'évaluer. À ce moment-là, le CPU découvre si sa supposition était bonne ou mauvaise.
Si la supposition s'avère juste, alors la branche est allée au bon endroit et les bonnes instructions ont été chargées dans le pipeline. S'il s'avère que la supposition était erronée, alors toutes les instructions qui ont été chargées dans le pipeline après que l'instruction de branchement conditionnel était erronée, elles doivent être rejetées et la récupération des instructions doit recommencer au bon endroit.
Amendement
En réponse au commentaire de StarWeaver, pour donner une idée de ce que le CPU doit faire pour exécuter une seule instruction:
Considérez quelque chose d'aussi simple que
MOV AX,[SI+10]
ce que nous, humains, considérons naïvement comme «charger AX avec le mot à SI plus 10». En gros, le CPU doit:C'est un énorme 10 étapes. Certaines de ces étapes seront optimisées même dans les processeurs non pipelinés, par exemple le CPU incrémentera presque toujours le PC en parallèle avec l'étape suivante, ce qui est une chose facile à faire car le PC est un registre très très spécial qui est jamais utilisé pour un autre travail, il n'y a donc aucune possibilité de conflit entre les différentes parties du CPU pour accéder à ce registre particulier. Mais encore, il nous reste 8 étapes pour une instruction aussi simple, et notez que je suppose déjà un certain degré de sophistication au nom du CPU, par exemple je suppose qu'il n'y aura pas besoin d'une étape supplémentaire entière pour le additionneur pour effectuer l'ajout avant de pouvoir en lire le résultat,
Maintenant, considérez qu'il existe des modes d'adressage plus compliqués, comme
MOV AX, [DX+SI*4+10]
, et même des instructions beaucoup plus compliquées, comme cellesMUL AX, operand
qui effectuent réellement des boucles à l'intérieur du CPU pour calculer leur résultat.Donc, mon point ici est que la métaphore du "niveau atomique" est loin d'être appropriée pour le niveau d'instruction CPU. Il peut convenir au niveau de l'étape du pipeline, si vous ne voulez pas aller trop loin jusqu'au niveau de la porte logique réelle.
la source
MOV AX,[SI+10]
sont étrangers, pas "simples"; la plupart des programmeurs n'ont jamais écrit d'assemblage. Nous ne «pensons pas naïvement» que cela signifie quelque chose.Pensez-y comme un road trip sans GPS. Vous arrivez à une intersection et pensez que vous devez tourner, mais vous n'êtes pas complètement sûr. Vous prenez donc le virage, mais demandez à votre passager de vérifier la carte. Peut-être que vous êtes à trois miles sur la route au moment où vous avez fini de vous disputer sur votre position. Si vous aviez raison, vous êtes à trois milles plus loin que vous ne l'auriez été si vous vous étiez arrêté et argumenté avant de tourner. Si vous vous trompiez, vous devez vous retourner.
Les pipelines CPU fonctionnent de la même manière. Au moment où ils peuvent vérifier l'état, ils sont déjà en chemin. La différence est qu'ils n'ont pas à reculer de trois milles, ils perdent juste l'avance. Cela signifie qu'il n'y a aucun mal à essayer.
la source
D'après ma compréhension, la prédiction de branche est plus utile lorsque la condition que vous devez vérifier nécessite le résultat de quelque chose qui est cher ou encore en cours, et vous seriez sinon en train de tourner les pouces en attendant la valeur pour évaluer la condition.
Avec des choses comme l'exécution dans le désordre, vous pouvez utiliser la prédiction de branche pour commencer à remplir des espaces vides dans le pipeline que le CPU ne pourrait pas utiliser autrement. Dans une situation où il n'y a, pour une raison quelconque, aucun cycle inactif dans le pipeline, alors oui, il n'y a pas de gain dans la prédiction de branche.
Mais la clé ici est que le processeur commence le travail pour l'une des branches prédites car il ne peut pas encore évaluer la condition elle-même.
la source
Forme courte:
Certains processeurs peuvent commencer à travailler sur une nouvelle instruction avant de terminer l'ancienne. Ce sont les CPU qui utilisent la prédiction de branche.
Un exemple de pseudocode:
Le code ci-dessus vérifie une condition et en fonction du résultat, il doit renvoyer la valeur stockée à l'emplacement de mémoire
addThis
ou la valeur stockée àreadThat
. Si la prédiction de branchement prédit la conditiontrue
, le CPU lira déjà la valeur stockée à l'emplacement de mémoireaddThis
tout en effectuant le calcul nécessaire pour évaluer l'if
instruction. Ceci est un exemple simplifié.la source
Oui, la condition est vérifiée dans les deux cas. Mais l'avantage de la prédiction de branche est que vous pouvez travailler au lieu d'attendre le résultat du contrôle de condition.
Disons que vous devez écrire un essai et qu'il peut s'agir du sujet A ou du sujet B. Vous savez d'après les essais précédents que votre professeur aime mieux le sujet A que B et le choisit plus souvent. Au lieu d'attendre sa décision, vous pouvez commencer à rédiger l'essai sur le premier sujet. Maintenant, il y a deux résultats possibles:
Les processeurs modernes tournent au ralenti la plupart du temps car ils attendent des réponses d'E / S ou le résultat d'autres calculs. Ce temps peut être utilisé pour effectuer des travaux futurs.
Même si vous devez ignorer ce que vous faites en cette période d'inactivité - il est plus probable que ce soit plus efficace si vous avez la possibilité de deviner quel chemin le programme choisira. Et les processeurs modernes ont cette capacité.
la source