La memoria è memoria. Ma cose diverse possono accedere a quella memoria. La GPU può accedere alla memoria, la CPU può accedere alla memoria, forse altri bit hardware, qualunque sia.
Una cosa particolare ha un accesso "coerente" alla memoria se le modifiche apportate da altri a quella memoria sono visibili al. Ora, potresti pensare che sia follia. Dopotutto, se la memoria è stata cambiata, come potrebbe qualcuno forse non riuscire a vederlo?
In poche parole, cache.
Si scopre che la modifica della memoria è costosa. Quindi facciamo tutto il possibile per evitando cambiando la memoria a meno che non sia assolutamente necessario. Quando si scrive un singolo byte dalla CPU a un puntatore in memoria, la CPU non scrive ancora quel byte. O almeno, non per memoria. Lo scrive su una copia locale di quella memoria chiamata "cache".
Il motivo è che, in generale, le applicazioni non scrivono (o leggono) singoli byte. Hanno maggiori probabilità di scrivere (e leggere) molti byte, in piccoli blocchi. Quindi, se hai intenzione di eseguire un'operazione costosa come un carico di memoria o un archivio, devi caricare o archiviare un grosso frammento di memoria. Quindi memorizzi tutte le modifiche che intendi apportare a un blocco di memoria in una cache, quindi crea una singola scrittura di quel pezzo memorizzato nella cache nella memoria effettiva ad un certo punto nel futuro.
Ma se si dispone di due dispositivi separati che utilizzano la stessa memoria, è necessario assicurarsi che la scrittura di un dispositivo sia visibile ad altri dispositivi. La maggior parte delle GPU non è in grado di leggere la cache della CPU. E la maggior parte dei linguaggi della CPU non ha il supporto a livello di linguaggio per dire "hey, quella roba che ho scritto alla memoria? Voglio davvero che tu la scriva ora nella memoria". Quindi di solito hai bisogno di qualcosa per garantire la visibilità dei cambiamenti.
In Vulkan, la memoria che viene etichettato come "HOST_COHERENT" significa che, se si scrive a che la memoria (tramite un puntatore mappato, dal momento che è l'unico modo Vulkan consente di scrivere direttamente nella memoria), si non lo fai necessità utilizzare funzioni speciali per assicurarsi che la GPU possa vedere tali modifiche. La visibilità della GPU di qualsiasi modifica è garantita. Se questo flag non è disponibile in memoria, è necessario utilizzare le API Vulkan per garantire la coerenza delle regioni specifiche di dati a cui si desidera accedere.
Con la memoria coerente, una delle due cose sta accadendo in termini di hardware. O l'accesso della CPU alla memoria non è memorizzato nella cache in nessuna delle cache della CPU, o la GPU ha accesso diretto alle cache della CPU (forse perché si trova sullo stesso dado delle CPU). Di solito si può dire che quest'ultimo sta accadendo, perché le implementazioni su GPU on-die di Vulkan non si preoccupano di offrire opzioni di memoria non coerenti.
"coerente" significa che se un oggetto dati è accessibile da più agenti (o su più percorsi), ognuno vedrà esattamente lo stesso stato. I due agenti possono essere una CPU e una GPU. L'esempio per due percorsi di lettura può essere tramite cache di trama rispetto alla cache L1. Mantenere la coerenza di solito richiede meccanismi hardware aggiuntivi, ad es. bit per il tracciamento dello stato delle linee della cache MESI o MOESI e possono portare a una quantità significativa di traffico di coerenza per la spedizione dei dati in giro, soprattutto se ci sono molti agenti. – njuffa
La cache di texture in GPU è un tipico esempio di meccanismo "incoerente". Se i dati sottostanti a una mappatura della trama cambiano, qualsiasi contenuto memorizzato nella cache della trama non può essere invalidato o aggiornato, e i successivi accessi alla cache della trama comportano la lettura dei dati non aggiornati. – njuffa