Domanda

Qual è la differenza tra allineati e non allineati di accesso alla memoria?

Io lavoro su un TMS320C64x DSP, e voglio utilizzare le funzioni intrinseche (C funzioni per le istruzioni di montaggio) e ha

ushort & _amem2(void *ptr);
ushort & _mem2(void *ptr);

dove _amem2 non allineato accesso di 2 byte e _mem2 non unaligned di accesso.

Quando devo usare che?

È stato utile?

Soluzione

Un accesso memoria allineato significa che il puntatore (come numero intero) è un multiplo di un valore specifico tipo chiamato l'allineamento. L'allineamento è il multiplo indirizzo naturale dove il tipo deve essere, o può essere memorizzata (per esempio per motivi di prestazioni) su una CPU. Ad esempio, una CPU potrebbe richiedere che tutti i carichi di due byte o esercizi vengono effettuate attraverso indirizzi che sono multipli di due. Per piccoli tipi primitivi (minori di 4 byte), l'allineamento è quasi sempre la dimensione del tipo. Per le strutture, l'allineamento è di solito l'allineamento massima di ogni utente.

Il compilatore C mette sempre variabili che si dichiarano a indirizzi che soddisfano l'allineamento "corretto". Quindi, se ptr punti per esempio una variabile uint16_t, sarà allineato ed è possibile utilizzare _amem2. È necessario utilizzare _mem2 solo se si sta accedendo per esempio un array di byte imballato ricevuto tramite I / O, o byte nel mezzo di una stringa.

Altri suggerimenti

Molti informatici architetture di memoria nei "parola" di diversi byte. Ad esempio, l'architettura Intel 32 bit memorizza parole di 32 bit, ciascuno di 4 byte. La memoria viene affrontata a livello di byte singolo, tuttavia; quindi un indirizzo può essere "allineato", che significa che parte da un confine di parola, o "non allineato", che significa che non.

In alcune architetture determinate operazioni di memoria possono essere più lenta o addirittura completamente non accettati indirizzi non allineati.

Quindi, se si conoscono gli indirizzi sono allineati sugli indirizzi giusti, è possibile utilizzare _amem2 (), per la velocità. In caso contrario, è necessario utilizzare _mem2 ().

Allineate gli indirizzi sono quelli che sono multipli di accesso dimensioni in questione.

  • L'accesso di 4 byte parole sugli indirizzi che sono più di 4 saranno allineati
  • L'accesso di 4 byte dall'indirizzo (dire) 3 (accesso unaligned

È molto probabile che la _mem2 funzione che funzionerà anche per i non allineati accessi saranno meno ottimale per ottenere i corretti allineamenti di lavoro nel suo codice.Questo significa che il _mem2 la funzione è probabile che sia costoso, quindi il suo _amem2 versione.

Così, quando avete bisogno di prestazioni (soprattutto quando si sa che la latenza di accesso è alta) sarebbe prudente per identificare quando è possibile utilizzare l'allineamento di accesso.Il _amem2 esiste per questo, allo scopo di offrire prestazioni elevate, quando si sa che l'accesso è allineato.

Quando si tratta di 2 byte accessi, identificazione allineati funzionamento è molto semplice.
Se tutti l'accesso indirizzi per l'operazione sono 'anche' (che è, la loro LSB è pari a zero), si dispone di 2 byte di allineamento.Questo può essere facilmente controllata con il,

if (address & 1) // is true
    /* we have an odd address; not aligned */
else
    /* we have an even address; its aligned to 2-bytes */

So che questa è una vecchia questione con una risposta selezionata sbagliando di poco visto nessuno spiegare la risposta a ciò che è la differenza tra l'accesso alla memoria allineati e non allineati ...

Che si tratti di DRAM o SRAM o flash o altro. Prendere una SRAM come semplice esempio è costruito su un bit SRAM specifico sarà costruita su un numero fisso di bit ampi e un numero fisso di file in profondità. permette di dire di larghezza 32 bit e diversi / molte righe profondo.

se faccio una scrittura 32 bit per affrontare 0x0000 in questo SRAM, il controllore di memoria SRAM risolvere questo può semplicemente fare un singolo ciclo di scrittura di riga 0.

se faccio una scrittura 32 bit per affrontare 0x0001 in questo SRAM, assumendo che è consentito, il controllore dovrà fare una lettura di riga 0, modificare tre dei byte, conservando uno, e scrivere che a riga 0, quindi leggere riga 1 modificare un byte lasciando gli altri tre come trovato e scrivere quella posteriore. che byte ottenere modificati o non hanno a che fare con endian per il sistema.

Il primo è allineato e quest'ultimo non allineati, chiaramente una differenza di prestazioni più bisogno logica extra per essere in grado di fare le quattro cicli di memoria e unire le corsie di byte.

Se leggessi 32 bit dall'indirizzo 0x0000 allora una singola lettura di riga 0, fatto. Ma leggere da 0x0001 e devo fare due letture row0 e row1 e in funzione del progetto del sistema basta inviare tali 64 bit al processore, eventualmente, due orologi di bus invece di uno. o il controllore di memoria e la logica supplementare in modo che i 32 bit sono allineate sul bus di dati in un ciclo di bus.

16 bit legge sono un po 'meglio, una lettura da 0x0000, 0x0001 e 0x0002 sarebbe solo una lettura da row0 e potrebbe base del dimensionamento dell'impianto / processore inviare tali 32 bit schiena e il processore li estrae o spostarla in controller di memoria in modo che atterrano su piste byte specifico in modo che il processore non deve ruotare intorno. Uno o l'altro deve se non entrambi. Una lettura da 0x0003 se è come sopra è necessario leggere riga 0 e row1 come uno dei byte è in ogni e quindi l'invio a 64 bit posteriori per il processore per estrarre o controllore di memoria combina i bit in una risposta bus a 32 bit ( assumendo il bus tra il controllore processore e la memoria è largo 32 bit per gli esempi).

Una scrittura 16 bit se finisce sempre con almeno una lettura-modifica-scrittura in questo esempio SRAM, indirizzo 0x0000, 0x0001 e 0x0002 lettura row0 modificare due byte e scrivere indietro. indirizzo 0x0003 letto due righe modificare un byte ogni e scrivere indietro.

8 bit è sufficiente per leggere una riga contenente quel byte, scrive anche se sono una lettura-modifica-scrittura di una riga.

Il non ha ancora ARMv4 come non allineato anche se si poteva disattivare la trappola e il risultato non è come ci si aspetterebbe di cui sopra, non è importante, le armi attuali consentono non allineati e vi darà il comportamento precedente si può cambiare un po 'in un registro di controllo e poi si annullerà trasferimenti non allineati. MIPS abituato a non permettere, non so cosa fanno ora. 86, 68K ecc, è stato consentito e il controller di memoria può aver avuto a che fare la maggior parte del lavoro.

I disegni che dont permettono che sono chiaramente per le prestazioni e meno logica a ciò che qualcuno potrebbe dire che è un peso per gli altri programmatori potrebbero dire che è senza lavoro supplementare sul programmatore o più facile per il programmatore. allineati o non si può anche vedere il motivo per cui può essere meglio non cercare di salvare la memoria, rendendo 8 variabili bit, ma andare avanti e bruciare una parola a 32 bit o qualunque sia la dimensione naturale di un registro o l'autobus è. Può aiutare le prestazioni ad un piccolo costo di alcuni byte. Per non parlare del codice aggiuntivo il compilatore avrebbe bisogno di aggiungere per rendere la lascia per dire a 32 bit registro simulare una variabile a 8 bit, mascheramento e talvolta firmare l'estensione. Dove utilizzando registri formati nativi tali istruzioni supplementari non sono necessari. È anche possibile confezionare più cose in una / posizione vasta bus di memoria e fare un ciclo di memoria per raccogliere o scrivere loro quindi utilizzare alcune istruzioni in più per manipulate tra registri non costano ariete e di un eventuale lavaggio sul numero di istruzioni.

I dont d'accordo che il compilatore sempre di allineare il diritto di dati per il target, ci sono modi per rompere questo. E se l'obiettivo doesnt sostenere unaligned vi ha colpito il guasto. I programmatori avrebbero mai bisogno di parlare di questo, se il compilatore sempre fatto bene basa su alcun codice legale che si potrebbe venire con, non ci sarebbe alcun motivo per questa domanda meno che non fosse per le prestazioni. se non controllare l'indirizzo vuoto ptr essere allineati o no, allora è necessario utilizzare il MEM2 () l'accesso non allineato tutto il tempo o che si hanno a che fare un if-then-else nel codice in base al valore della ptr come nik sottolineato. dichiarando come vuoto il compilatore C ora non ha alcun modo per affrontare correttamente con l'allineamento e che non sarà garantita. se si prende un char * prt e dei mangimi a queste funzioni tutte le scommesse sono fuori dal compilatore ottenere nel modo giusto senza di te l'aggiunta di codice aggiuntivo sia sepolto nella funzione MEM2 () o al di fuori di questi due funzioni. così come scritto nella tua domanda MEM2 () è l'unica risposta corretta.

DRAM dire utilizzato nel vostro desktop / laptop tende ad essere 64 o 72 (con ecc) i bit di larghezza, ed ogni accesso ad essi è allineato. Anche se le memory stick sono in realtà costituiti da 8 bit di larghezza o 16 o 32 bit larghi chip. (Puo essere cambiando con cellulari / compresse per vari motivi) il controllore di memoria e idealmente almeno una cache di siede di fronte a questo dram modo che gli accessi non allineati o anche allineate che sono più piccoli della larghezza del bus lettura-modifica-scrittura sono trattate con nella SRAM cache, che è modo più veloce, e gli accessi DRAM sono tutti allineati larghezza accessi al bus. Se non si dispone di cache di fronte alla DRAM e il controller è progettata per tutta la larghezza gli accessi che poi è la peggiore performance, se progettato per illuminare le corsie byte separatamente (assumendo ampie chip a 8 bit), allora non avete la lettura-modifica -scrive ma un controllore più complicato. se il caso tipico utilizzo è con una cache (se ce n'è uno nella progettazione) allora non può avere senso per avere quel lavoro supplementare nel controller per ogni corsia di byte, ma hanno semplicemente sapere come fare larghezza piena bus trasferimenti dimensioni o multipli.

_mem2 è più generale. Sarà funziona se PTR è allineato o meno. _amem2 è più rigoroso: esso richiede che ptr essere allineati (anche se è presumibilmente leggermente più efficiente). Così utilizzare _mem2 meno che non si può garantire che PTR è sempre allineato.

Molti processori hanno restrizioni di allineamento in materia di accesso di memoria. Accesso unaligned sia genera un interrupt un'eccezione (ad esempio ARM), o è solo più lento (ad esempio 86).

_mem2 è probabilmente implementato come recupero due byte e utilizzando shift e operazioni bit per bit o per effettuare una 16 bit ushort fuori di essi.

_amem2 probabilmente appena legge l'ushort a 16 bit dal PTR specificato.

Non so TMS320C64x specificamente, ma direi che è necessario riallineare a 16 bit per la memoria a 16 bit accede. Così si può utilizzare <=> sempre ma con penalizzazione delle prestazioni, e <=> quando è possibile garantire che PTR è un indirizzo pari.

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