Sui processori x86 esiste un modo per caricare i dati dalla normale memoria di scrittura nei registri senza passare attraverso la gerarchia della cache?Come evitare l'inquinamento della cache durante il caricamento di un flusso di numeri
Il mio caso d'uso è che ho una struttura di grande ingrandimento (Hash map o B-Tree). Sto lavorando su un grande flusso di numeri (molto più grande del mio L3 ma adatto alla memoria). Quello che sto cercando di fare è molto semplice:
int result = 0;
for (num : stream_numbers) {
int lookup_result = lookup_using_b_tree(num);
result += do_some_math_that_touches_registers_only(lookup_result);
}
return result;
Dato che io sto visitando ogni numero una sola volta e la somma di tutti i numeri è più che la dimensione L3 Immagino che finiranno per sfrattare alcune linee di cache che contengono parti del mio albero B. Preferirei invece non avere alcun numero da questa cache di esecuzione del flusso poiché non hanno alcuna localizzazione temporale (solo letti una volta). In questo modo posso massimizzare le possibilità che il mio albero B rimanga nella cache e le ricerche siano più veloci.
Ho esaminato le istruzioni (v)movntdqa
disponibili in SSE 4.1 per i carichi temporali. Non sembra essere una buona idea, perché sembra funzionare solo per la scrittura non combinabile che combina la memoria. Questo antico article da Intel sostiene che:
Le future generazioni di processori Intel possono contenere ottimizzazioni e miglioramenti per carichi di streaming, come ad esempio un maggiore utilizzo dei buffer di carico di streaming e il supporto per i tipi di memoria aggiuntive, creando ancora più opportunità per il software sviluppatori per aumentare le prestazioni e l'efficienza energetica delle loro applicazioni.
Tuttavia, non sono a conoscenza di alcun processore di oggi. Ho letto elsewhere che un processore può semplicemente scegliere di ignorare questo suggerimento per la memoria di scrittura e utilizzare invece uno movdqa
. Quindi c'è un modo per ottenere carichi dalla normale memoria di scrittura senza passare attraverso la gerarchia della cache sui processori x86, anche se è possibile solo su Haswell e sui modelli successivi? Gradirei anche qualche informazione su se questo sarà possibile in futuro?
Una domanda simile è stata posta di recente, potreste essere interessati anche a [questo] (http://stackoverflow.com/q/28684812/417501). – fuz
@FUZxxl: Questo è stato chiarito come motivo di benchmarking, che è piuttosto diverso. Questo è più simile a http://stackoverflow.com/questions/37889896/intel-instructions-for-access-to-memory-which-skips-cache, che in realtà non è un duplicato della domanda di benchmarking. –
AFAIK non c'è un modo affidabile/garantito per farlo. 'prefetchnta' potrebbe essere utile, ma, ancora una volta, non è chiaro se può fare qualcosa di utile, dal momento che non sovrascrive la semantica della coerenza della cache di ordine forte dei tipi di memoria WB. Penso che il meglio che puoi sperare sia prefetchnta o movntdqa da caricare nella cache e impostare i dati LRU per quella linea per indicare che sarebbe un buon obiettivo di sfratto. Quindi, se l'hardware funziona effettivamente in questo modo, si spera che i dati di questo stream eliminino semplicemente le righe precedenti dallo stesso flusso una volta che ha una voce in ogni set. –