Domanda

Devo ammettere che non capisco. Diciamo che avete una memoria con una parola di memoria di lunghezza 1 byte. Perché non si può accedere a una variabile lungo 4 byte in un unico accesso alla memoria su un indirizzo non allineata (cioè. Non è divisibile per 4), come è il caso con gli indirizzi allineati?

È stato utile?

Soluzione

E 'una limitazione di molti processori sottostanti. E 'di solito può essere aggirato facendo 4 inefficiente singolo byte recupera piuttosto che una parola efficace recuperare, ma molti progettisti lingua decise che sarebbe stato più facile solo per mettere fuori legge loro e la forza di tutto per essere allineati.

Ci sono molte più informazioni in questo link che il PO ha scoperto.

Altri suggerimenti

Il sottosistema di memoria su un processore moderno è limitato a accesso alla memoria alla granularità e l'allineamento della sua dimensione di parola; questo è il caso per una serie di motivi.

Velocità

I processori moderni hanno più livelli di memoria cache che i dati devono essere tirati attraverso; supporto singolo byte legge renderebbe il throughput sottosistema di memoria strettamente legata alla portata unità di esecuzione (alias CPU-bound); tutto questo è che ricorda come PIO è stato superato da DMA per molte delle stesse ragioni di dischi rigidi.

La CPU sempre si legge nella sua dimensione della parola (4 byte su un processore a 32-bit), in modo che quando si fa un non allineato accesso indirizzo - su un processore che lo sostiene - il processore sta per leggere più parole. La CPU leggerà ogni parola di memoria che il vostro indirizzo richiesto a cavallo. Questo fa sì che un'amplificazione fino a 2X il numero di transazioni di memoria richiesti per accedere ai dati richiesti.

A causa di questo, può facilmente essere lento leggere due byte di quattro. Per esempio, supponiamo di avere una struttura in memoria che assomiglia a questo:

struct mystruct {
    char c;  // one byte
    int i;   // four bytes
    short s; // two bytes
}

Su un processore a 32 bit si sarebbe molto probabilmente allineate come illustrato di seguito:

Struct Layout

Il processore può leggere ciascuno di questi componenti in un'unica transazione.

Diciamo che ha avuto una versione compatta della struct, forse dalla rete in cui è stato confezionato per l'efficienza di trasmissione; potrebbe essere simile a questa:

Packed struct

La lettura del primo byte sta per essere lo stesso.

Quando si chiede al processore di darvi 16 bit da 0x0005 dovrà leggere una parola da da 0x0004 e spostare a sinistra 1 byte per collocarlo in un registro a 16 bit; qualche lavoro extra, ma la maggior parte in grado di gestire che in un ciclo.

Quando si chiede per 32 bit da 0x0001 si otterrà un'amplificazione di 2X. Il processore leggerà da 0x0000 nel registro risultato e spostamento a sinistra 1 byte, quindi leggere nuovamente da 0x0004 in un registro temporaneo, spostamento a destra 3 byte, allora OR con il registro risultato.

Gamma

Per un determinato spazio di indirizzi, se l'architettura può assumere che i 2 bit meno significativi sono sempre 0 (ad esempio, macchine a 32 bit), allora possono accedere 4 volte più memoria (i 2 bit memorizzati possono rappresentare 4 stati distinti), oppure la stessa quantità di memoria con 2 bit per qualcosa come bandiere. Prendendo le 2 LSB al largo di un indirizzo darebbe un allineamento a 4 byte; anche indicato come un passo di 4 byte. Ogni volta che un indirizzo è incrementato viene efficacemente incrementando bit 2, non bit 0, cioè, gli ultimi 2 bit continuerà sempre ad essere 00.

Questo può anche influenzare la progettazione fisica del sistema. Se il bus indirizzi bisogno 2 meno bit, ci possono essere 2 meno piedini sulla CPU, e 2 meno tracce sul circuito.

Atomicity

La CPU può operare su una parola di memoria allineato atomicamente, che significa che nessuna altra istruzione può interrompere tale operazione. Questo è fondamentale per il corretto funzionamento di molti lock-liberi strutture dati e altri paradigmi concorrenza .

Conclusione

Il sistema di memoria di un processore è un po 'più complesso e complicato che qui descritto; una discussione sulla come un processore x86 effettivamente Indirizzi memoria può aiutare (molti processori funzionano in modo simile ).

Ci sono meventuali ulteriori vantaggi per aderire a l'allineamento di memoria che si possono leggere a questo articolo IBM .

uso primario di un computer è quello di trasformare i dati. Moderne architetture e tecnologie di memoria sono stati ottimizzati per decenni per facilitare ottenere più dati, in, out, e tra sempre più veloci unità-in un modo altamente affidabile esecuzione.

Bonus: Cache

Un altro allineamento-per-performance che ho accennato precedentemente è allineamento sulle linee di cache che sono (per esempio, su alcune CPU) 64B.

Per ulteriori informazioni su quanto le prestazioni possono essere guadagnato facendo leva cache, un'occhiata a Galleria di processore cache effetti ; da questo on-line cache di dimensioni

  

La comprensione delle linee di cache può essere importante per alcuni tipi di ottimizzazioni di programma. Ad esempio, l'allineamento dei dati può stabilire se un'operazione tocca una o due linee di cache. Come abbiamo visto nel precedente esempio, questo può facilmente significa che in caso disallineato, l'operazione sarà due volte più lento.

è possibile con alcuni processori ( The Nehalem può fare questo ), ma in precedenza tutti gli accessi di memoria è allineata sul 64 bit (o) linea 32 bit, perché il bus è lunga 64 bit, si doveva recuperare 64 bit alla volta, ed era significativamente più facile recuperare questi in 'pezzi' allineate di 64 bit.

Quindi, se si voleva ottenere un singolo byte, è recuperato il pezzo a 64 bit e quindi mascherate i bit che non volevi. Facile e veloce se il byte era alla fine giusto, ma se fosse nel bel mezzo di quella a 64 bit pezzo, che avrebbe dovuto mascherare i bit indesiderati e quindi spostare i dati sopra al posto giusto. Peggio ancora, se si voleva una variabile di 2 byte, ma che è stato diviso tra 2 pezzi, quindi quello richiesto il doppio della memoria richiesta accessi.

Quindi, come tutti pensano di memoria è a buon mercato, hanno appena fatto il compilatore allineare i dati sul pezzo del processore dimensioni in modo il codice viene eseguito più rapido ed efficiente a costo di memoria sprecata.

Fondamentalmente, il motivo è perché il bus di memoria ha una certa lunghezza specifica che è molto, molto più piccola della dimensione della memoria.

Quindi, la CPU legge dalla cache L1 on-chip, che viene spesso 32kb in questi giorni. Ma il bus di memoria che collega la cache L1 alla CPU avrà la larghezza notevolmente minore della dimensione di riga di cache. Questo sarà dell'ordine di 128 bit .

262,144 bits - size of memory
    128 bits - size of bus

accessi disallineati volte sovrappongono due linee di cache, e ciò richiederà una completamente nuova cache di lettura per ottenere i dati. Si potrebbe anche perdere tutta la via d'uscita alla DRAM.

Inoltre, una parte della CPU dovrà stare sulla sua testa unire un unico oggetto su queste due differenti linee di cache che hanno ciascuno una parte di dati. Su una linea, sarà nei bit di ordine elevato molto, nell'altro, i bit di ordine basso molto.

Ci saranno hardware dedicato completamente integrato nella tubazione che gestisce oggetti in movimento allineati sui bit necessari del bus di dati della CPU, ma tale hardware può essere privo di oggetti allineati, perché probabilmente ha più senso usare tali transistori per eccesso di velocità correttamente i programmi ottimizzati.

In ogni caso, la seconda memoria letto che a volte è necessario rallenterebbe la pipeline non importa quanto l'hardware speciale-scopo era (ipoteticamente e stupidamente) dedicato a rattoppare le operazioni di memoria non allineati.

@joshperry ha dato una risposta eccellente a questa domanda. Oltre alla sua risposta, ho alcuni numeri che mostrano graficamente gli effetti che sono stati descritti, in particolare l'amplificazione 2X. Ecco un link ad un Google foglio di calcolo mostrando ciò che l'effetto di diversi allineamenti di parole assomigliano. Inoltre ecco un link ad un Github succo con il codice per il test. Il codice di prova è adattato da l'articolo scritto da Jonathan Rentzsch che @joshperry riferimento. I test sono stati eseguiti su un MacBook Pro con un quad-core a 2,8 GHz Intel Core i7 processore a 64-bit e 16 GB di RAM.

entrare descrizione dell'immagine qui

Se un sistema con memoria byte indirizzabile ha una scala a 32 bit bus di memoria, che significa che ci sono effettivamente quattro sistemi di memoria a livello di byte che sono tutti cablati per leggere o scrivere lo stesso indirizzo. Una lettura di 32 bit allineato richiederà informazioni memorizzate nello stesso indirizzo in tutti i quattro sistemi di memoria, in modo che tutti i sistemi in grado di fornire dati simultaneamente. Un 32-bit di lettura non allineati richiederebbe alcuni sistemi di memoria per restituire i dati da un indirizzo, e un po 'per restituire i dati dal successivo indirizzo più alto. Anche se ci sono alcuni sistemi di memoria che sono ottimizzati per essere in grado di soddisfare tali richieste (in aggiunta al loro indirizzo, hanno efficacemente un "uno più" segnale che causa loro di utilizzare un indirizzo uno superiore a quella specificata) tale funzione aggiunge un costo considerevole e la complessità di un sistema di memoria; la maggior parte dei sistemi di memoria merce semplicemente non possono restituire porzioni diverse parole di 32 bit allo stesso tempo.

Se si dispone di un bus dati a 32 bit, le linee di indirizzo bus indirizzi legati alla memoria partirà da A 2 , in modo che solo a 32 bit allineati gli indirizzi si può accedere in un unico ciclo di bus.

Quindi, se una parola si estende da un indirizzo allineamento di confine - cioè A 0 per 16/32 dati di bit o A 1 per i dati a 32 bit sono zero, due cicli di bus sono necessari per ottenere i dati.

Alcune architetture e / o insiemi di istruzioni non supportano l'accesso non allineati e genererà un'eccezione su tali tentativi, così codice compilatore generato accesso allineato richiede non solo cicli di bus addizionali, ma ulteriori istruzioni, rendendo ancora meno efficiente.

Il PowerPC è possibile caricare un numero intero da un indirizzo dispari senza problemi.

Sparc e I86 e (credo) Itatnium sollevare eccezioni hardware quando si tenta questo.

Un carico di 32 bit vs quattro carichi 8 bit non sta andando a fare un sacco di differenza sulla maggior parte dei processori moderni. Se i dati sono già nella cache o non avrà un effetto di gran lunga maggiore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top