Modifica: ST non consente di pubblicare più di due collegamenti per principianti. Ci scusiamo per i riferimenti mancanti.Verifica senza blocco per la modifica di uno stato condiviso globale in C utilizzando l'allineamento Cache-Line
Sto provando a ridurre l'overhead di blocco in un'applicazione C in cui rilevare le modifiche su uno stato globale è rilevante per le prestazioni. Anche se ultimamente ho letto molto sull'argomento (ad esempio molto da H. Sutter e molti altri) non sono sicuro della mia implementazione. Vorrei utilizzare una combinazione di un CAS come il funzionamento e DCL per un controllo su una variabile globale Cache-Line Allineati, evitando così falsi-sharing, per aggiornare filettatura dati locali da dati condivisi tra più thread. La mia mancanza di fiducia è dovuto principalmente alla
- me non riuscendo a interpretare la documentazione GNU su Type-Attributes
- io non sembrano essere in grado di trovare alcuna documentazione e gli esempi che potrei facilmente si traducono in C, come ad esempio aligning- a-cache-line-e-sapere-the-cache-line-size su ST o 1 (anche se sembra rispondere alla mia domanda un po 'io non sono fiducioso con la mia implementazione)
- la mia esperienza con C è limitato
Le mie domande:
il tipo di attributi documentazione afferma:
Questo attributo specifica un allineamento minimo (in byte) per le variabili del tipo specificato. Ad esempio, le dichiarazioni:
(vedi documenti di attributi di dichiarazione)
forza il compilatore di assicurare (per quanto possibile) che ogni variabile il cui tipo è
struct S
o saranno assegnatimore_aligned_int
e allineato almeno su un limite8-byte
. Su un SPARC, avente tutte le variabili di tipostruct S
allineato8-byte
confini consente al compilatore di utilizzare la LDD e std (carico di doppia e memorizzare) istruzioni per copiare una variabile di tipo struct S all'altro, migliorando così l'efficienza di runtime .Vuol dire che l'inizio del
struct S
omore_aligned_int
sarà sempre allineato al8-byte
confine? Ciò non significa che i dati verranno riempiti per utilizzare esattamente 64 byte, giusto?Presupposto 1.È vero che ogni caso di
struct cache_line_aligned
(vedi codice Esempio 1 sotto) allinea il64-byte
confini e utilizzare esattamente una cache di riga (supponendo cache-linee sono64 bytes
lunghezza)Uso
typedef
per la dichiarazione di tipo no alterare la semantica di__attribute__ ((aligned (64)))
(vedi codice Esempio 2 sotto)non ho bisogno di usare
aligned_malloc
quando si crea un'istanza della struct se struct è dichiarato con__attribute__ ...
// Example 1
struct cache_line_aligned {
int version;
char padding[60];
} __attribute__ ((aligned (64)));
// Example 2
typedef struct {
int version;
// place '__attribute__ ((aligned (64)))' after 'int version'
// or at the end of the declaration
char padding[60];
} cache_line_aligned2 __attribute__ ((aligned (64)));
E infine uno schizzo di una funzione che utilizza l'approccio allineato di cache-line per controllare in modo efficiente se stato globale è stato modificato da qualche altro thread:
void lazy_update_if_changed(int &t_version, char *t_data) {
// Assuming 'g_cache_line_aligned' is an instance of
// 'struct cache_line_aligned' or 'struct cache_line_aligned2'
// and variables prefixed with 't_' being thread local
if(g_cache_line_aligned.version == t_version) {
// do nothing and return
} else {
// enter critical section (acquire lock e.g. with pthread_mutex_lock)
t_version = g_cache_line_aligned.version
// read other data that requires locking where changes are notified
// by modifying 'g_cache_line_aligned.version', e.g. t_data
// leave critical section
}
}
Ci scusiamo per il lungo post.
Grazie!
Cheers! questo ha chiarito molto bene le cose. Non ho pensato di usare sizeof per verificare l'allineamento! Lo ricorderò questo. Che dire delle strutture allineate allocate dinamicamente? 'Align_malloc' farà il lavoro? – instilled
Probabilmente lo farà. Leggi la sua documentazione per essere sicuro. –
Sicuro! Lo farà. Grazie ancora per la brillante risposta. – instilled