Domanda

I processori Intel a 32 bit come Pentium dispongono di bus dati a 64 bit e pertanto recuperano 8 byte per accesso. Sulla base di questo, presumo che gli indirizzi fisici che questi processori emettono sul bus degli indirizzi siano sempre multipli di 8.

In primo luogo, questa conclusione è corretta?

In secondo luogo, se è corretto, si dovrebbero allineare i membri della struttura dati su un limite di 8 byte. Ma ho visto persone usare un allineamento a 4 byte invece su questi processori.

Come possono essere giustificati nel farlo?

È stato utile?

Soluzione

La consueta regola empirica (direttamente dai manuali di ottimizzazione di Intels e AMD) è che ogni tipo di dati dovrebbe essere allineato in base alle proprie dimensioni. Un int32 dovrebbe essere allineato su un limite di 32 bit, un int64 su un limite di 64 bit e così via. Un carattere si adatta perfettamente ovunque.

Un'altra regola pratica è, ovviamente, " al compilatore è stato detto dei requisiti di allineamento " ;. Non devi preoccuparti perché il compilatore sa aggiungere il giusto riempimento e offset per consentire un accesso efficiente ai dati.

L'unica eccezione è quando si lavora con le istruzioni SIMD, in cui è necessario garantire manualmente l'allineamento sulla maggior parte dei compilatori.

  

In secondo luogo, se è corretto, quindi uno   dovrebbe allineare i membri della struttura dati su   un limite di 8 byte. Ma ho visto   persone che utilizzano un allineamento a 4 byte   invece su questi processori.

Non vedo come questo faccia la differenza. La CPU può semplicemente emettere una lettura per il blocco a 64 bit che contiene quei 4 byte. Ciò significa che ottiene 4 byte extra prima dei dati richiesti o dopo. Ma in entrambi i casi, richiede una sola lettura. L'allineamento a 32 bit di dati a 32 bit assicura che non attraversi un limite di 64 bit.

Altri suggerimenti

Il bus fisico ha una larghezza di 64 bit ... multiplo di 8 - > Sì

TUTTAVIA, ci sono altri due fattori da considerare:

  1. Alcuni set di istruzioni x86 sono indirizzati a byte. Alcuni sono allineati a 32 bit (ecco perché hai una cosa a 4 byte). Ma nessuna istruzione (core) è allineata a 64 bit. La CPU può gestire l'accesso ai dati non allineato.
  2. Se ti preoccupi delle prestazioni, dovresti pensare alla linea della cache, non alla memoria principale. Le linee della cache sono molto più ampie.

Sono giustificati nel farlo perché la modifica dell'allineamento a 8 byte costituirebbe un cambiamento ABI e il miglioramento marginale delle prestazioni non vale la pena.

Come ha già detto qualcun altro, le cache sono importanti. Tutti gli accessi sul bus di memoria effettivo sono in termini di linee di cache (64 byte su x86, IIRC). Vedi il & Quot; Ciò che ogni programmatore deve sapere sulla memoria & Quot; documento che è stato già menzionato. Quindi il traffico di memoria effettivo è allineato a 64 byte.

Per l'accesso casuale e fintanto che i dati non sono disallineati (ad es. attraversare un confine), non penso che contino molto; l'indirizzo corretto e l'offset nei dati possono essere trovati con un semplice costrutto AND nell'hardware. Diventa lento quando un accesso in lettura non è sufficiente per ottenere un valore. Questo è anche il motivo per cui i compilatori di solito mettono insieme valori piccoli (byte, ecc.) Perché non devono avere un offset specifico; i cortometraggi dovrebbero essere su indirizzi pari, 32 bit su indirizzi a 4 byte e 64 bit su indirizzi a 8 byte.

Nota che se hai un caching involesso e un accesso lineare ai dati, le cose saranno diverse.

Il bus a 64 bit a cui si fa riferimento alimenta le cache. Come CPU, leggi e scrivi sempre intere righe della cache. La dimensione di una riga della cache è sempre un multiplo di 8 e il suo indirizzo fisico è effettivamente allineato con offset di 8 byte.

I trasferimenti da cache a registro non usano il database esterno, quindi la larghezza di quel bus è irrilevante.

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