P6 Architecture - Inscrivez-vous renommant côté, ne les registres utilisateur limitées, il existe plus ops passé déversant / chargement?

StackOverflow https://stackoverflow.com/questions/2460198

Question

J'étudie la conception JIT en ce qui concerne la mise en œuvre des langages dynamiques VM. Je ne l'ai pas fait beaucoup depuis l'Assemblée les 8086/8088 jours, un peu ici ou là, donc bien si je suis de mauvaise humeur.

Si je comprends bien, l'architecture x86 (IA-32) a toujours le même ensemble de registre limité de base aujourd'hui toujours fait, mais le nombre de registre interne a augmenté considérablement, mais ces registres internes ne sont généralement pas disponibles et sont utilisés avec changement de nom de registre pour obtenir le pipelining parallèle de code qui autrement ne pourraient pas être parallélisables. Je comprends très bien cette optimisation, mais mon sentiment est, alors que ces optimisations aident dans le rendement global et pour les algorithmes parallèles, l'ensemble de registre limité, nous sommes toujours coincés avec des résultats dans plus registre déversant frais généraux tels que si x86 avait double, ou quadruple les registres à notre disposition, il peut y avoir beaucoup moins opcodes push / pop dans un flux d'instructions typique? Ou y at-il d'autres optmizations processeur qui permettent d'optimiser également cette distance que je ne connais? En gros, si j'ai une unité de code qui dispose de 4 registres pour travailler avec pour le travail entier, mais mon unité a une douzaine de variables, j'ai potentiellement un push / pop pour 2 ou si des instructions.

Toutes les références à des études, ou mieux encore, des expériences personnelles?

EDIT: x86_64 dispose de 16 registres, soit le double x86-32, merci pour la correction et d'information

.
Était-ce utile?

La solution

En plus de renommer les registres pour masquer les bulles en raison de latences d'instruction, la plupart des architectures x86 sont assez intelligents pour compter et pousse pops et renommer les registres sur aussi bien. Rappelez-vous que le décodeur d'instructions sur le x86 exécute en fait une sorte de compilation JIT, transformant le flux d'instructions x86 dans un petit programme de microcode stocké dans le cache de trace. Une partie de ce procédé consiste à intercepter les charges d'empilage de petits offset et en tournant dans les registres ainsi. Ainsi, quelque chose comme (la manifestement stupide et purement par exemple):

lwz eax,[ebp]
lwz ebx,[ebp+4]
add eax,[edx+0]
push eax 
lwz eax,[ebp+8]
add eax,ebx
pop ebx
add eax,ebx

cuisiniers en quelque chose comme (semblant registres internes sont nommés par exemple r0..r16):

lw r3, edx
lw r1, ebp
lw r2, ebp+4 ; the constant '4' is usually stored as an immediate operand
add r1,r2
or r4,r1,r1 ;; move r1 to r4
lw r1, ebp+8
add r1,r2
or r2,r4,r4
add r1,r2

Bien sûr, un décodeur par magie à puce (contrairement à celui qui correspond en fait dans nombre de transistors) s'effondrerait certains des mouvements inutiles là-bas, mais ce que je fais est que push / pop et magasins / charges à esp+(some small number) sont effectivement transformés en registres d'ombre.

Autres conseils

Deux points:

(1) x86-64 double le nombre de registres à 16

(2) dans les CPU x86 modernes, une instruction qui utilise un emplacement de mémoire qui est déjà dans le cache L1 est presque aussi vite que la même opération avec un opérande de registre, de sorte que vous pouvez presque penser L1 comme "registre mémoire"

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top