Sto usando Linux e la piattaforma x86 a 8 core. Innanzitutto come trovo la dimensione della riga della cache.
$ getconf LEVEL1_DCACHE_LINESIZE
64
Passa il valore come definizione di macro al compilatore.
$ gcc -DLEVEL1_DCACHE_LINESIZE=`getconf LEVEL1_DCACHE_LINESIZE` ...
In fase di esecuzione sysconf(_SC_LEVEL1_DCACHE_LINESIZE)
può essere utilizzato per ottenere la dimensione della cache L1.
Per conoscere le dimensioni, è necessario cercarlo utilizzando la documentazione per il processore, afaik non esiste un modo programmatico per farlo. Tra i lati positivi, tuttavia, la maggior parte delle righe della cache ha dimensioni standard, basate sugli standard Intel. Sulla cache x86 le linee sono 64 byte, tuttavia, per evitare false condivisioni, devi seguire le linee guida del processore che stai prendendo di mira (intel ha alcune note speciali sui suoi processori basati su netburst), generalmente devi allinearti a 64 byte per questo (intel afferma che dovresti anche evitare di oltrepassare i limiti di 16 byte).
Per fare ciò in C o C++ è necessario utilizzare lo standard aligned_alloc
funzione o uno degli identificatori specifici del compilatore come __attribute__((align(64)))
o __declspec(align(64))
. Per riempire i membri in una struttura per suddividerli su diverse righe di cache, è necessario inserire un membro abbastanza grande da allinearlo al limite successivo di 64 byte
Un altro modo semplice è quello di eseguire il cat di /proc/cpuinfo:
grep cache_alignment /proc/cpuinfo
Non esiste un modo completamente portatile per ottenere la dimensione della cacheline. Ma se sei su x86/64, puoi chiamare il cpuid
istruzioni per ottenere tutto ciò che ti serve sapere sulla cache, inclusa la dimensione, la dimensione della cacheline, quanti livelli, ecc...
http://softpixel.com/~cwright/programming/simd/cpuid.php
(scorri un po' verso il basso, la pagina parla di SIMD, ma ha una sezione che recupera la cacheline.)
Per quanto riguarda l'allineamento delle strutture dati, non esiste nemmeno un modo completamente portatile per farlo. GCC e VS10 hanno modi diversi per specificare l'allineamento di una struttura. Un modo per "hackerarlo" è riempire la struttura con variabili inutilizzate finché non corrisponde all'allineamento desiderato.
Per allineare il tuo mallocs(), tutti i compilatori tradizionali hanno anche funzioni malloc allineate a tale scopo.