2015-12-23 13 views
7

Ho letto su wikipedia che la disattivazione CPU-cache può migliorare le prestazioni:Come posso disabilitare la cache della cpu per determinate regioni di memoria?

Marcatura alcuni intervalli di memoria come non-cacheable può migliorare le prestazioni, evitando la cache di regioni di memoria raramente ri-accessibili.

Quando ho cercato su Google come farlo in C su Linux, tuttavia, non ho trovato nulla. Non è che ho davvero bisogno di questa funzione, ma sono comunque interessata.

E sai di progetti che utilizzano questa ottimizzazione?

Edit: sto programmando per x86_64

+0

Questo dipende molto dalla piattaforma. Per quale piattaforma stai programmando? – fuz

+1

La tua domanda sembra avere una risposta qui http://stackoverflow.com/questions/9544094/c-working-with-the-cpu-cache – Abstraction

+0

@Abstraction La risposta riguarda Windows, ma OP sta usando Linux. Inoltre, linguaggio sbagliato. – fuz

risposta

6

quel commento sul non-caching non significa che cosa pensate che significhi, e dove viene utilizzato, di solito non è una funzionalità accessibile all'utente. Cioè, il controllo della cache della CPU è in genere un'operazione privilegiata.

Detto questo ...

- Un programma utente normale può essere costruire con le funzioni che di attributi sono "caldo" o "freddo" per lasciare che il compilatore dire il caricatore di raggruppare le funzioni in modi che utilizzeranno la cache più utile.

- Un programma normale può utilizzare la funzione madvise() in linux per dire alla funzione di paginazione varie cose, incluso il fatto che la memoria appena usata è o non è probabile che possa essere riutilizzata presto.

- Il kernel stesso utilizza i flag di tipo Memory Range Range (mtrr) e Page Attribute Table (pat) nei kernel successivi, per indicare all'hardware determinati intervalli di memoria (come il buffer di visualizzazione mappato in memoria e il varie parti del bus PCI) non devono essere memorizzate nella cache.

"Normal Data ™", come è probabile che si utilizzi in qualsiasi programma in C, lo essenzialmente non trarrebbe mai vantaggio dal contrassegnare i propri dati in modo non memorizzabile nella cache. Il miglioramento delle prestazioni ottenuto dai dati non memorizzati nella cache è la successiva assenza delle varie operazioni di cache-flush e di memoria che i dispositivi mappati in memoria e i buffer di visualizzazione avrebbero bisogno quasi costantemente. Ad esempio, la posa di una cache su un dispositivo mappato in memoria richiederebbe un comando di invalidazione della cache prima di ogni lettura e un comando di scrittura forzata della cache dopo ogni singola scrittura per assicurarsi che le letture e le scritture avvengano nel momento esatto necessario. Ciò "avvelenerà" l'uso della cache, utilizzando e scartando immediatamente le linee della cache (una risorsa fisicamente limitata) in un modo non ostile e inutile.

Nel raro caso in cui si scriva un programma che accede a una di queste regioni nocive della cache, ad esempio se si scrivesse parte del server di visualizzazione X su un sistema Linux, il kernel avrebbe già impostato i registri per il dispositivo e il comportamento non cache sarebbe trasparente per te.

Non c'è praticamente alcun tempo in cui il normale programma di valutazione delle applicazioni trarrà vantaggio dalla possibilità di contrassegnare una variabile come dannosa per la cache oltre il diverso tipo di utilizzo di madvise().

Anche allora, i casi erano si può ottenere qualsiasi beneficio sono così rare che se avessi mai acutally eseguito in uno, il set di problema avrebbe incluso la necessità e la metodologia come parte della vostra ricerca e desideri è stato detto come e perché così esplicitamente non avresti mai avuto bisogno di fare questa domanda.

Per tornare di nuovo allo stesso esempio, se si stesse scrivendo il driver necessario, durante la lettura sull'hardware dell'adattatore di visualizzazione o sul bus PCI, i vari indicatori e tecniche sarebbero stati documentati e discussi nella guida hardware.

Ci sono modi per estrarre l'espulsione della cache e tale dallo spazio utente con cose come l'istruzione CLCLEAR su una piattaforma Intel. Queste tecniche saranno non migliorare le prestazioni generali.

Poiché si tratta di un'operazione privilegiata su un sistema Linux, è possibile che scriva un driver del kernel che ha acquisito e contrassegnato una regione di memoria come non accessibile e quindi consente di mapparlo nell'applicazione. Ma la necessità di una regione del genere è così rara e così probabile che venga utilizzata in modo improprio, che non esiste una metodologia normale per farlo sul posto.

Quindi come si fa? Non lo fai, almeno non il te che sei oggi. Quando diventi uno scrittore di driver del kernel con una conoscenza approfondita del codice multi-threaded e dei problemi di sincronizzazione dei dati, saprai come potresti farlo, e a quel punto capirai perché non vuoi eccetto come ultima risorsa.

TL; DR: a causa del modo in cui linux utilizza e gestisce dati e codice, non vi è mai un vantaggio per contrassegnare qualsiasi parte di un'applicazione normale come non memorizzabile che non provoca più crepacuore di quella che salva. Come tale, non ci sono API non privilegiate per fare ciò.

P.S. Inoltre, detto questo, qualcuno ha già indicato le cose che portano a questo articolo http://lwn.net/Articles/255364/ che spiega come rendere il programma molto facile da usare nella cache e alcuni dei modi in cui è possibile eseguire alcune operazioni di bypass della cache molto a buon mercato. Ad esempio, l'uso di memset() tende ad aggirare la cache durante l'impostazione della memoria, e alcune operazioni possono "scorrere" la cache. Questa non è la stessa cosa di quello che chiedi, ma una volta compreso tutto l'articolo avrai una migliore comprensione del perché contrassegnare una regione di memoria come non trattabile di solito è, come dicono i Jedi, non la soluzione che sei cercando.

0

Recentemente ho avuto bisogno di sperimentare con la memoria senza cache in un'applicazione multi-threaded pesante cache.

Mi è venuto in mente questo kernel module che consente di mappare la memoria non collegata nello spazio utente.

Il processo utente richiede memoria non collegata chiamando mmap() sul dispositivo dei caratteri del modulo (vedere la directory di test per la demo).

What every programmer should know about memory è davvero una lettura obbligata!

Problemi correlati