Domanda

Attualmente sto cercando di creare un codice che dovrebbe funzionare su una vasta gamma di macchine, dalle tasche e dai sensori palmari ai grandi server nei data center.

Una delle (molte) differenze tra queste architetture è il requisito per l'accesso allineato alla memoria.

L'accesso alla memoria allineata non è richiesto su CPU x86 "standard", ma molte altre CPU ne hanno bisogno e producono un'eccezione se la regola non viene rispettata.

Fino ad ora, mi sono occupato costringendo il compilatore a essere cauto su specifici accessi ai dati noti per essere rischiosi, utilizzando l'attributo pack (o pragma). E funziona bene.

Il problema è che il compilatore è così cauto che molte prestazioni vengono perse nel processo.

Poiché le prestazioni sono importanti, sarebbe meglio riscrivere una parte del codice per lavorare in modo specifico su CPU allineate strettamente. Tale codice, d'altra parte, sarebbe più lento su CPU che supportano l'accesso alla memoria non allineato (come x86), quindi vogliamo usarlo solo su CPU che richiedono un accesso alla memoria allineato rigorosamente.

E ora la domanda: come rilevare, in fase di compilazione, che l'architettura di destinazione richiede un accesso alla memoria strettamente allineato? (o viceversa)

È stato utile?

Soluzione

Nessuna implementazione C che io conosca fornisce alcuna macro del preprocessore per aiutarti a capirlo. Poiché il tuo codice presumibilmente funziona su una vasta gamma di macchine, presumo che tu abbia accesso a un'ampia varietà di macchine per il test, quindi puoi capire la risposta con un programma di prova. Quindi puoi scrivere la tua macro, qualcosa come di seguito:

#if defined(__sparc__)
/* Unaligned access will crash your app on a SPARC */
#define ALIGN_ACCESS 1
#elif defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC)
/* Unaligned access is too slow on a PowerPC (maybe?) */
#define ALIGN_ACCESS 1
#elif defined(__i386__) || defined(__x86_64__) || \
      defined(_M_IX86) || defined(_M_X64)
/* x86 / x64 are fairly forgiving */
#define ALIGN_ACCESS 0
#else
#warning "Unsupported architecture"
#define ALIGN_ACCESS 1
#endif

Nota che la velocità di un accesso non allineato dipenderà dai confini che attraversa. Ad esempio, se l'accesso attraversa un confine di pagina 4k sarà molto più lento e potrebbero esserci altri confini che lo rendono ancora più lento. Anche su x86, alcuni accessi non allineati non sono gestiti dal processore e sono invece gestiti dal kernel del sistema operativo. È incredibilmente lento.

Non vi è inoltre alcuna garanzia che un'implementazione futura (o attuale) non cambierà improvvisamente le caratteristiche di prestazione degli accessi non allineati. Questo è accaduto in passato e potrebbe accadere in futuro; il PowerPC 601 perdonava molto l'accesso non allineato ma il PowerPC 603e non lo era.

A complicare ulteriormente le cose è il fatto che il codice che scriveresti per creare un accesso non allineato differirebbe nell'implementazione tra le piattaforme. Ad esempio, su PowerPC è semplificato dal fatto che x << 32 e x >> 32 sono sempre 0 se x è a 32 bit, ma su x86 non hai questa fortuna.

Altri suggerimenti

Scrivere il codice per un rigoroso allineamento della memoria è comunque una buona idea.Anche sui sistemi x86 che consentono l'accesso non allineato, le tue letture / scritture non allineate causeranno due accessi alla memoria e alcune prestazioni andranno perse.Non è difficile scrivere codice efficiente che funzioni su tutte le architetture di CPU.La semplice regola da ricordare è che il puntatore deve essere allineato alla dimensione dell'oggetto che stai leggendo o scrivendo.per esempio.se si scrive un DWORD, allora (dest_pointer & 3== 0).L'utilizzo di una stampella come i tipi "UNALIGNED_PTR" causerà la generazione di codice inefficiente da parte del compilatore.Se hai una grande quantità di codice legacy che deve funzionare immediatamente, allora ha senso usare il compilatore per "risolvere" la situazione, ma se è il tuo codice, scrivilo dall'inizio per funzionare su tutti i sistemi.

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