2010-03-17 6 views
5

Sto studiando la progettazione JIT per quanto riguarda l'implementazione di linguaggi dinamici VM. Non ho fatto molte assemblee dal giorno 8086/8088, solo un po 'qua e là, quindi sii gentile se sono fuori di testa.Architettura P6 - Registra la rinomina a parte, i registri utente limitati risultano in più operazioni di spargimento/caricamento spesi?

A quanto ho capito, l'architettura x86 (IA-32) ha ancora lo stesso set di registri di base limitato che ha sempre fatto, ma il numero di registri interni è cresciuto enormemente, ma questi registri interni non sono generalmente disponibili e sono utilizzato con la rinomina del registro per ottenere un pipelining parallelo di codice che altrimenti non potrebbe essere parallelizzabile. Capisco bene questa ottimizzazione, ma il mio sentimento è che, mentre queste ottimizzazioni aiutano nel throughput complessivo e per gli algoritmi paralleli, il set di registri limitati siamo ancora bloccati con risultati in più overhead del registro in modo tale che se x86 avesse il doppio o quadruplicasse i registri a nostra disposizione, ci possono essere molti meno codici opzionali push/pop in un flusso di istruzioni tipico? O ci sono altre ottimizzazioni del processore che ottimizzano questo aspetto di cui non sono a conoscenza? Fondamentalmente se ho un'unità di codice che ha 4 registri con cui lavorare per il lavoro intero, ma la mia unità ha una dozzina di variabili, ho potenzialmente un push/pop per ogni 2 o più istruzioni.

Eventuali riferimenti a studi o, meglio ancora, esperienze personali?

MODIFICA: x86_64 ha 16 registri, che è doppio x86-32, grazie per la correzione e le informazioni.

risposta

9

Oltre a ridenominare i registri per nascondere le bolle a causa delle latenze delle istruzioni, la maggior parte delle architetture x86 è abbastanza intelligente da contare i push e pop e rinominarli anche nei registri. Ricorda che il decodificatore di istruzioni su x86 esegue effettivamente una sorta di compilazione JIT, trasformando il flusso di istruzioni x86 in un piccolo programma microcodice memorizzato nella cache di traccia. Parte di questo processo include l'intercettazione di carichi di stack di piccole dimensioni e la loro conversione anche in registri. Così simile (la palesemente stupido e puramente per esempio):

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 

cucina in qualcosa di simile (finta registri interni sono denominati es 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 

Naturalmente un magicamente il decodificatore intelligente (a differenza di quello che si adatta effettivamente al conteggio dei transistor) collasserebbe alcune delle mosse non necessarie, ma il punto che sto facendo è che push/pop e memorizza/carichi su esp+(some small number) vengono effettivamente trasformati in registri ombra.

+0

Grazie CrashWorks, ottima risposta. Hai un buon riferimento per questo? Ho diversi libri di architettura e nessuno di loro menziona questo, ma era il mio sospetto che stesse succedendo qualcosa del genere. – codenheim

+1

È possibile dedurre molte di queste informazioni dal capitolo 2 del manuale di ottimizzazione di Intel (http://www.intel.com/products/processor/manuals/). Puoi anche eseguire alcuni esperimenti controllati per cercare di capire alcuni degli interni della "scatola nera". E potresti sempre dare un'occhiata ai brevetti di Intel: dopotutto, lo scopo di un brevetto è che devono dirti come funziona! # 5740414 potrebbe essere un punto di partenza. – Crashworks

+0

Grazie, buoni punti. Il primo passo è ordinare nuovi manuali rispetto a quelli di 15 anni.:) – codenheim

4

due punti:

(1) x86-64 raddoppia il numero di registri da 16

(2) nella CPU x86 moderni, un'istruzione che utilizza un'area di memoria che è già nella cache L1 quasi veloce come la stessa operazione con un operando di registro, quindi puoi quasi pensare a L1 come "memoria registro"

+0

Re: (2) - Ho temporizzato la latenza di un L1 * hit * sul mio i7 a circa 9 cicli, che (sorprendentemente) è in realtà più lento del Core Duo. – Crashworks

+0

Come hai fatto a farlo? Dovrebbe essere solo 2 cicli su un Core i7, penso, il che non dovrebbe essere un problema su un flusso di istruzioni ragionevolmente ben programmato. –

+0

Oggetto: (1), ora di aggiornare i miei manuali hardware. Ho 386, 486 e Pentium ma niente di più recente. Grazie a tutti e due ragazzi per le risposte. – codenheim