Perché posso gestire manualmente la cache della GPU, ma non la cache della CPU?

2

Sulla GPU, ogni thread ha accesso alla memoria "condivisa" o "locale", che è analoga alla cache nella CPU. Quindi, invece di memorizzare nella cache la pagina più recente, posso dire al mio programma quali pezzi di memoria saranno utilizzati più frequentemente e mantenere manualmente quelli nella cache. La mia domanda è: perché i progettisti di CPU non consentono un'operazione analoga? Cioè perché non posso dire alla CPU, "OK, i nodi di questo albero non sono sulla stessa pagina in memoria, ma ho bisogno di accedervi molto, quindi malloc li nella cache per me"?

    
posta Elliot Gorokhovsky 28.08.2016 - 00:21
fonte

2 risposte

4

Questo tipo di gestione della memoria: dire alla cpu (in anticipo) a quale contenuto si accede frequentemente, è davvero difficile da fare per una vasta gamma di problemi di programmazione, in cui le strutture dati implicano puntatori e simili.

Eppure è (per confronto) più facile da fare per alcuni algoritmi a fette parallele, come nel dominio grafico. Nel dominio della grafica, hai a che fare con grossi pezzi di dati contigui (numerici) e con un numero di puntatori decisamente inferiore.

Quindi, le moderne CPU optano per la gestione della cache automaticamente, utilizzando cache multilivello che alla fine finiscono con la memoria basata su disco. Ogni livello della cache nota la frequenza con cui viene utilizzata una porzione di memoria memorizzata nella cache e utilizza tali informazioni quando decide di rimuovere qualcosa dal livello della cache. Ogni livello ha una diversa dimensione di "pagina" (chiamata dimensione della linea nei livelli superiori).

Quindi, non c'è praticamente alcun modo per un programmatore di informare la CPU di cosa tenere e cosa eliminare, a causa della combinazione di dimensioni multilinea e di cache di ogni livello. Ok, quindi è già abbastanza brutto, ma ora, getta dentro che lo stesso programma vuole essere eseguito su più cpus differenti di prestazioni diverse (dove gran parte della differenza di prestazioni deriva dall'aumento delle dimensioni della cache, del numero di livelli di cache, ecc.), E , quindi questo diventa un problema intrattabile per il programmatore che si occupa di algoritmi e strutture dati generali.

Ciò che un programmatore può fare, quindi, invece di informare la cpu su cosa mantenere / sfrattare, è cercare di co-localizzare gli elementi correlati (ad esempio A e B) in modo che attraverso tutte le possibili variazioni di cpu e cache multi-livello, se A è nella cache, allora lo è anche B. (Ci sono altre cose che i programmatori possono tentare di mantenere i programmi cache friendly, puoi google "cache friendly" struttura dati o algoritmi.)

Un'altra differenza è che la memoria della GPU è separata dalla memoria della CPU, quindi la programmazione della GPU implica necessariamente lo spostamento della memoria avanti e indietro. Mentre la CPU ha errori di cache e di pagine che caricano automaticamente la memoria che non è vicina alla CPU, la GPU (storicamente) non ha questi meccanismi ei programmatori della GPU devono costantemente istruire la GPU per copiare la memoria avanti e indietro tra la memoria della GPU e la memoria della CPU. Questo è stato ed è sempre più un problema poiché usiamo le GPU per risolvere più problemi, quindi alla fine vedremo sempre più hardware abbattere la barriera tra la memoria della CPU e la memoria della GPU, con conseguente unificazione a livelli più alti della gerarchia della cache.

    
risposta data 28.08.2016 - 03:09
fonte
2

Ci sono molte ragioni per cui le CPU usano una cache piuttosto che un semplice blocco di memoria più veloce. Ma direi che il più grande è questo.

Le cache sono state inventate principalmente come mezzo di ottimizzazione per gli accessi alla memoria. E questo potrebbe funzionare solo se può accadere in modo trasparente , a programmi che sono già stati scritti e compilati. Pertanto, forzare un programma a fare manualmente il caching non sarebbe utile.

Il caching è stato progettato per essere trasparente. Permette ai programmi di beneficiare di diverse dimensioni e architetture della cache senza doverli scrivere esplicitamente. Quello che vuoi è qualcosa di meno che trasparente, qualcosa che funziona davvero bene solo se si programma per un'architettura specifica.

Ecco perché a volte vedi questo tipo di cose ... nelle CPU embedded . È noto che le CPU embedded specializzate forniscono accesso a una piccola quantità di SRAM veloce, in alcuni casi sacrificando una percentuale della cache dei dati. Questo è fatto precisamente perché sono incorporati; il codice scritto per queste circostanze è specializzato e non intende essere multipiattaforma.

Inoltre, per correggere alcune informazioni errate:

On the GPU, each thread has access to "shared" or "local" memory, which is analogous to cache on the CPU.

No, non è analogo a una cache della CPU. Affatto. Quando le GPU eseguono gli accessi alla memoria, di solito lo fanno attraverso le cache, proprio come fanno le CPU.

La memoria locale del gruppo di lavoro non è pensata per essere una cache. principalmente esiste per la rapida intercomunicazione tra invocazioni all'interno di un gruppo di lavoro. Ecco perché tutti i thread in un gruppo di lavoro ottengono le stesse dichiarazioni delle variabili locali. Certo, puoi dividerlo e usarlo come memoria aggiuntiva per thread. Ma questo non è il suo scopo principale.

    
risposta data 28.08.2016 - 03:53
fonte

Leggi altre domande sui tag