Per quanto posso dire, hai sbagliato un po '. Stai guardando nella direzione sbagliata, le cose fresche e pratiche qui sono nel codice, non nelle applicazioni.
Questo è spiegato in OpenGL wiki , anche se è necessario applicare un certo sforzo per ottenere ciò che è così interessante esso:
Consider a shader that reads from a location, adds 1 to it, and then writes to it. It is theoretically possible for two such shaders to read from and and write to the same location in the same image at the same time. Because of the way memory accesses are handled, it is entirely possible that this sequence of events works like this:
- Shader A reads the image value, say 0.
- Shader B reads the image value, also 0.
- Shader B adds 1 to its local value of 0, becoming 1.
- Shader B writes its local value to the image. The image now has 1.
- Shader A adds 1 to its local value of 0, becoming 1.
- Shader A writes its local value to the image. The image now has 1.
Vedi cosa c'è di sbagliato in sopra? Guarda, il valore dell'immagine è destinato a passare a 0 then 1 then 2
, ma va solo a 1
: questo significa che otterrai grigio chiaro dove intendevi grigio scuro o forse otterrai verde se sei davvero sfortunato - questo è comportamento indeterministico .
Bene, non vedrai cose brutte come quella nelle applicazioni reali prima ancora che fossero introdotti gli atomici, ma quanto è costato a programmatore ? Pensaci, per evitare effetti collaterali, il programmatore dovrebbe sincronizzare manualmente gli shader, in modo che il loro codice fosse simile a quello:
- entra nella sezione sincronizzata
- Shader A legge il valore dell'immagine, diciamo 0.
- Shader A aggiunge 1 al suo valore locale di 0, diventando 1.
- Shader A scrive il suo valore locale sull'immagine. L'immagine ora ha 1.
- esci dalla sezione sincronizzata
- entra nella sezione sincronizzata
- Shader B legge il valore dell'immagine, è garantito che sia 1 ora, che bello
(se dimentichiamo che il programmatore ha dovuto scrivere 3 istruzioni extra per farlo bene).
- Shader B aggiunge 1 al suo valore locale di 1, diventando 2.
- Shader B scrive il suo valore locale sull'immagine. L'immagine ora ha 2.
- esci dalla sezione sincronizzata
Ora, come stato wiki,
Atomic operations prevent this possibility entirely. Each shader's independent atomic operation will fully complete before the next one starts.
Cosa significherebbe per programmatore? Vediamo, vogliamo ancora i nostri due shader in add that 1 twice so that 0 becomes 2
. Okie dokie, eccoci qui ...
- Shader A
reads-modifies-writes
del valore dell'immagine in un passo, 0 è garantito per diventare 1.
- Shader B
reads-modifies-writes
del valore dell'immagine in un passo, 1 è garantito diventare 2.
... e questo è tutto. Questo è tutto. Questo è tutto!!! Abbiamo due dichiarazioni (che sono abbastanza facili da leggere btw) a partire da 10 che rendono il rendering e la sincronizzazione misti in modo non particolarmente apparente.
Sei mai stato sottoposto a modifiche al codice come questo? Sono stato e, beh, questa è una delle esperienze più cool, più carine, più sexy che si possano immaginare.
Oh applicazioni ... hai chiesto informazioni su queste, giusto? Bene, le applicazioni sembreranno e si comportano allo stesso modo. Ci saranno solo 5 volte meno codice lì, se questo ti interessa.