Il sottosistema di memoria su un moderno processore è limitato all'accesso alla memoria per la 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 estratti; il supporto di letture a byte singolo renderebbe il throughput del sottosistema di memoria strettamente legato al throughput dell'unità di esecuzione (aka cpu-bound); questo ricorda tutto il modo in cui la modalità PIO è stata superata da DMA per molte delle stesse ragioni nei dischi rigidi.
La CPU legge sempre alla sua dimensione di parola (4 byte su un processore a 32 bit), quindi quando si fa un accesso di indirizzo non allineato - su un processore che lo supporta - il processore leggerà più parole. La CPU leggerà ogni parola di memoria su cui si trova il tuo indirizzo richiesto. Ciò provoca un'amplificazione fino a 2 volte il numero di transazioni di memoria richieste per accedere ai dati richiesti.
Per questo motivo, può essere molto più lento leggere due byte che quattro. Ad esempio, supponiamo di avere una struttura in memoria simile a questa:
struct mystruct {
char c; // one byte
int i; // four bytes
short s; // two bytes
}
Su un processore a 32 bit sarebbe molto probabilmente allineato come mostrato qui:
Il processore può leggere ciascuno di questi membri in una transazione.
Supponiamo che tu abbia una versione impacchettata della struttura, magari dalla rete in cui è stata imballata per l'efficienza della trasmissione; potrebbe assomigliare a questo:
La lettura del primo byte sarà la stessa.
Quando chiedi al processore di darti 16 bit da 0x0005, dovrà leggere una parola da 0x0004 e spostare a sinistra di 1 byte per inserirlo in un registro a 16 bit; del lavoro extra, ma la maggior parte può gestirlo in un ciclo.
Quando chiedi 32 bit da 0x0001 otterrai un'amplificazione 2X. Il processore leggerà da 0x0000 nel registro dei risultati e sposta a sinistra di 1 byte, quindi rileggerà da 0x0004 in un registro temporaneo, sposta a destra di 3 byte, quindi OR
con il registro dei risultati.
Gamma
Per un determinato spazio di indirizzi, se l'architettura può assumere che i 2 LSB siano sempre 0 (ad es. Macchine a 32 bit), può accedere a 4 volte più memoria (i 2 bit salvati possono rappresentare 4 stati distinti), o la stessa quantità di memoria con 2 bit per qualcosa come bandiere. Rimuovere i 2 LSB da un indirizzo ti darebbe un allineamento di 4 byte; indicato anche come un passo di 4 byte. Ogni volta che un indirizzo viene incrementato, aumenta effettivamente il bit 2, non il bit 0, ovvero gli ultimi 2 bit continueranno sempre ad essere 00
.
Ciò può anche influire sulla progettazione fisica del sistema. Se il bus dell'indirizzo richiede 2 bit in meno, possono esserci 2 pin in meno sulla CPU e 2 tracce in meno sul circuito.
Atomicita
La CPU può operare atomicamente su una parola di memoria allineata, il che significa che nessun'altra istruzione può interrompere tale operazione. Ciò è fondamentale per il corretto funzionamento di molte strutture dati senza blocco e altri paradigmi di concorrenza .
Conclusione
Il sistema di memoria di un processore è un po 'più complesso e coinvolto di quanto descritto qui; una discussione su come un processore x86 si occupa effettivamente della memoria può aiutare (molti processori funzionano in modo simile).
Ci sono molti altri vantaggi nell'aderire all'allineamento della memoria che puoi leggere in questo articolo IBM .
L'uso principale di un computer è trasformare i dati. Le architetture e le tecnologie di memoria moderne sono state ottimizzate nel corso di decenni per facilitare l'ottenimento di più dati, in, out e tra unità di esecuzione più e più veloci, in modo altamente affidabile.
Bonus: cache
Un altro allineamento per prestazioni a cui ho accennato in precedenza è l'allineamento sulle linee della cache che sono (ad esempio, su alcune CPU) 64B.
Per ulteriori informazioni su quante prestazioni possono essere ottenute sfruttando le cache, dai un'occhiata alla Gallery of Processor Cache Effects ; da questa domanda sulle dimensioni della linea di cache
La comprensione delle linee della cache può essere importante per alcuni tipi di ottimizzazioni del programma. Ad esempio, l'allineamento dei dati può determinare se un'operazione tocca una o due righe della cache. Come abbiamo visto nell'esempio sopra, ciò può facilmente significare che in caso di disallineamento, l'operazione sarà due volte più lenta.