In che modo una CPU carica più byte contemporaneamente se la memoria è indirizzata a byte?

3

Ho letto le CPU e come sono implementate, e alcune architetture complesse (guardandoti x86) hanno istruzioni che vengono caricate dalla memoria durante un ciclo di clock. Poiché un indirizzo punta a un singolo byte, come è possibile che io possa scrivere:

mov eax, DWORD PTR ds:[esi]

dove sto caricando una doppia parola (4 byte!) dalla memoria e la chucking in eax . Come funziona con un solo ciclo di clock? Non dovrebbe accedere a 4 indirizzi? Il DWORD inizia da ds:[esi] e finisce con [ds:[esi] - 3] , il che significa che deve calcolare 4 indirizzi efficaci, ma lo fa in un ciclo.

Come?

Grazie

    
posta DylanG 03.01.2018 - 18:56
fonte

2 risposte

5

Poiché la larghezza del bus dati e la dimensione della più piccola unità indirizzabile sono due cose separate.

Solo perché puoi specificare gli indirizzi a livello di byte, non significa che devi avere un bus dati a 8 bit. La maggior parte (possibilmente tutti) i moderni processori x86 usano un bus dati a 64 bit e ogni tempo che leggono dalla memoria, leggono 64 bit. Se hai richiesto solo 8 bit, l'eccesso viene semplicemente scartato.

Se richiedi più di 64 bit (ad esempio, se carichi i registri SSE a 128 bit), ci saranno più accessi alla memoria.

Molti processori hanno anche un concetto di allineamento, che in pratica significa che ogni accesso alla memoria è su un indirizzo divisibile dalla larghezza del bus dati. La maggior parte può ancora recuperare la memoria non allineata, ma se attraversa un limite di allineamento (ad esempio, richiedendo 32 bit all'indirizzo 0xFC su un sistema allineato a 64 bit), otterrete più accessi alla memoria, anche se altrimenti si inserisse nel bus dati .

Ecco alcune altre note relative ad alcuni aspetti della tua domanda:

  • Un singolo accesso alla memoria richiede più tempo di un ciclo di clock della CPU. Molto, MOLTO più a lungo se non è nella cache L1. Vedi questo post per ordini di grandezza grezzi e tieni presente che 1 nanosecondo = 1 ciclo di clock a 1 GHz. Molte CPU desktop e laptop in questi giorni possono funzionare fino a 3 GHz o meno di 0,333 ... nanosecondi per ciclo.
  • Un ciclo di clock non equivale a un'istruzione. Le istruzioni (anche quelle che rimangono interamente all'interno della CPU, che non accedono a nessuna memoria o periferica) possono richiedere più cicli. Inoltre, possono essere eseguite più istruzioni contemporaneamente (e non mi riferisco a core multipli o hyperthreading qui, intendo istruzioni multiple eseguite simultaneamente su un singolo core, senza hyperthreading).
risposta data 03.01.2018 - 21:17
fonte
2

Come esempio per illustrare il funzionamento, parliamo prima di un classico processore a 32 bit come il buon vecchio 68020.

Per varie ragioni (compatibilità, usabilità per caratteri ASCII, ...), anche le CPU a 32 e 64 bit hanno nomi (chiamati "indirizzi") per singoli byte. Se la CPU ha bisogno di nominare un blocco più grande di memoria, ad es. 4 byte, usa il nome per il primo byte e implicitamente i seguenti byte sono quelli con i seguenti numeri di indirizzo.

D'altra parte, il bus può trasferire 32 bit contemporaneamente, poiché la CPU ha 32 linee dati D0 ... D32. Quindi, dei 32 bit di un indirizzo, i 2 bit inferiori selezionano un gruppo di linee dati (i bit 00 selezionano D0 ... D7, 01 seleziona D8 ... D15, 10 seleziona D16 ... D23, e 11 seleziona D24 ... D31). Solo i 30 bit di indirizzo più alti esistono come linee di indirizzo reali A2 ... A32. Invece dei 2 bit inferiori, la CPU ha quattro distinti segnali di selezione dei byte che può utilizzare singolarmente in combinazioni diverse.

Ora, se la CPU vuole leggere 32 bit dall'indirizzo 0x1000, può utilizzare tutte e 32 le linee dati in parallelo. Posiziona i 30 bit più alti sul bus degli indirizzi e imposta tutti e quattro i segnali di selezione dei byte, quindi trasferisce 4 byte.

Vediamo una panoramica:

  • leggere byte da 0x1000: bus indirizzo = 0x1000, byte-selezionare 0
  • leggere byte da 0x1001: indirizzo bus = 0x1000, byte-selezionare 1
  • leggere byte da 0x1002: bus indirizzo = 0x1000, byte-selezionare 2
  • leggere byte da 0x1003: indirizzo bus = 0x1000, byte-selezionare 3
  • leggere byte da 0x1004: indirizzo bus = 0x1004, byte-selezionare 0
  • lettura breve da 0x1000: bus indirizzo = 0x1000, byte-seleziona 0 + 1
  • lettura breve da 0x1002: bus indirizzo = 0x1000, byte-seleziona 2 + 3
  • leggi int da 0x1000: bus indirizzo = 0x1000, byte-seleziona 0 + 1 + 2 + 3
  • read (unaligned) int da 0x1002: (primo ciclo) Address bus = 0x1000, Byte-Select 2 + 3, quindi (secondo ciclo) Address bus = 0x1004, Byte-Select 0 + 1

Con le CPU attuali il principio rimane lo stesso, ma con la memoria cache interna non è più possibile osservare i singoli trasferimenti di byte del core della CPU dall'esterno. Accadono tra il core della CPU e la cache (entrambi on-chip). La memoria parla ora solo con la cache e il trasferimento avviene sempre in blocchi più grandi di un byte.

    
risposta data 03.01.2018 - 20:51
fonte

Leggi altre domande sui tag