2009-11-18 12 views
43

Sono interessato a forzare lo svuotamento della cache della CPU in Windows (per ragioni di benchmark, voglio emulare l'avvio senza dati nella cache della CPU), preferibilmente un'implementazione di base C o chiamata Win32.Come posso eseguire un flush della cache della CPU in x86 Windows?

Esiste un modo noto per eseguire questa operazione con una chiamata di sistema o anche qualcosa di subdolo come si fa a dire un grande memcpy?

Piattaforma Intel i686 (anche P4 e versioni successive).

risposta

49

Fortunatamente, c'è più di un modo per svuotare le cache in modo esplicito.

L'istruzione "wbinvd" ripristina il contenuto della cache modificato e contrassegna le cache vuote. Esegue un ciclo di bus per far sì che le cache esterne scarichino i loro dati. Sfortunatamente, è un'istruzione privilegiata. Ma se è possibile eseguire il programma di test sotto qualcosa come DOS, questa è la strada da percorrere. Questo ha il vantaggio di mantenere l'ingombro della cache del "SO" molto piccolo.

Inoltre, vi è l'istruzione "invd", che invalida le cache senza scaricandole nella memoria principale. Ciò viola la coerenza della memoria principale e della cache, quindi devi prenderti cura di te da solo. Non proprio raccomandato.

Per scopi di analisi comparativa, la soluzione più semplice è probabilmente la copia di un grande blocco di memoria in una regione contrassegnata con WC (combinazione di scrittura) anziché in WB. La regione mappata in memoria della scheda grafica è un buon candidato, oppure puoi contrassegnare una regione come WC da solo tramite i registri MTRR.

Si possono trovare alcune risorse su analisi comparativa routine brevi a Test programs for measuring clock cycles and performance monitoring.

+1

Ohh, sono corretto, pulito, non sapevo di questa istruzione. – Falaina

+1

L'istruzione di wbinvd ha un ordine di 2000-5000 cicli di clock da completare! La maggior parte delle istruzioni richiede in media 2-5. – unixman83

7

Esistono istruzioni di assemblaggio x86 per forzare la CPU a svuotare determinate linee della cache (come CLFLUSH), ma sono piuttosto oscure. In particolare CLFLUSH scarica solo un indirizzo scelto dalle cache L1.

qualcosa di subdolo come si dice una grande memcopy?

Sì, questo è l'approccio più semplice e farà in modo che la CPU svuota tutti i livelli di cache. Escludere semplicemente il tempo di svuotamento della cache dai benchmakrs e dovresti avere una buona idea di come il tuo programma funziona sotto la pressione della cache.

+1

"farà in modo che le vampate di CPU tutti i livelli di cache." Non è vero, come ho affermato, le CPU commerciali moderne, specialmente quando sono astratte da un sistema operativo, possono (e probabilmente hanno) strategie di memorizzazione nella cache molto complicate. – marr75

+4

Credo che stai confondendo la cache della CPU con altre cache a livello di sistema operativo. Il sistema operativo non ha praticamente alcun senso su ciò che la CPU memorizzerà nella cache o non nella cache, perché queste decisioni devono accadere così rapidamente, non c'è tempo per gli interrupt del kernel o simili. La cache della CPU è implementata esclusivamente in silicio. – intgr

+1

Un interruttore di contesto consentirà effettivamente l'esecuzione di altri processi e quindi inquinerà la cache. Ma questa è una parte normale del comportamento del sistema operativo, che avverrà con o senza il benchmark, quindi ha senso includerlo comunque nei tuoi tempi. – intgr

2

Non c'è purtroppo alcun modo per svuotare esplicitamente la cache. Alcune delle opzioni disponibili sono:

1.) Esegui il Thrash della cache eseguendo alcune operazioni di memoria molto ampie tra le iterazioni del codice che stai analizzando.

2.) Abilitare Cache Disable nello x86 Control Registers e confrontarlo. Questo probabilmente disabiliterà anche la cache delle istruzioni, che potrebbe non essere quello che vuoi.

3.) Implementare la parte del codice del proprio benchmarking (se possibile) utilizzando Non-Temporal instructions. Tuttavia, questi sono solo suggerimenti per il processore sull'utilizzo della cache, è ancora libero di fare ciò che vuole.

1 è probabilmente il più semplice e sufficiente per i vostri scopi.

Edit: Oops, mi correggo c'è un'istruzione per invalidare la cache x86, vedere la risposta di drhirsch

+1

L'affermazione che non ci sono istruzioni per il flushing della cache è errata. E riscrivere una routine usando istruzioni non temporali per il benchmarking è una sciocchezza. Se i dati utilizzati dalla routine si inseriscono nella cache, durante l'analisi comparativa rallenterebbe notevolmente, rendendo inutili le misurazioni. – hirschhornsalz

+0

Non è possibile svuotare esplicitamente la cache da Windows. Vi è negato l'accesso diretto all'hardware ... ci sono istruzioni di assemblaggio non portabili che possono farlo. – marr75

+2

Si può facilmente farlo in Windows 95,98, ME. E anche per le moderne varianti di Windows è possibile implementarlo in ring 0 utilizzando un driver. – hirschhornsalz

Problemi correlati