A che scopo?
Prendere la struttura tipica di un renderer posticipato. Costruisci i tuoi g-buffer, fai i tuoi passaggi di luce, fai un po 'di post-processing e tone mapping, magari getta delle cose trasparenti e poi presenti l'immagine finale. Ogni processo dipende dal completamento del processo precedente prima che possa iniziare. Non puoi passare l'illuminazione finché non hai finito il tuo g-buffer. E così via.
Come si può parallelizzare su più code di esecuzione? Non è possibile parallelizzare l'edificio g-buffer o i passaggi di illuminazione, poiché tutti questi comandi scrivono sulle stesse immagini allegate (e non è possibile farlo da più code). E se non stanno scrivendo le stesse immagini, allora dovrai scegliere una coda in cui combinare le immagini risultanti in quella finale. Inoltre, non ho idea di come funzioni il buffer di profondità senza utilizzare lo stesso buffer di profondità.
E quella combinazione avrebbe richiesto la sincronizzazione.
Ora, ci sono molte attività che possono essere parallele. Facendo macinare il frustum. Aggiornamenti del sistema di particelle. Trasferimenti di memoria Cose così; dati che sono destinati al successivo frame. Ma quante code potresti realisticamente tenere occupate in una volta? 3? Forse 4?
Per non parlare del fatto che è necessario creare un sistema di rendering che possa scalare. Vulkan non richiede che le implementazioni forniscano più di una coda. Quindi il tuo codice deve essere in grado di funzionare ragionevolmente su un sistema che offre solo una coda e un sistema che offre 16. E per trarre vantaggio da un sistema a 16 code, potrebbe essere necessario eseguire il rendering in modo molto diverso.
Oh, e si tenga presente che se si richiedono un sacco di code, ma non lo si utilizza , il rendimento potrebbe essere influenzato. Se si richiedono 8 code, l'implementazione non ha altra scelta che presumere che si intende essere in grado di emettere 8 serie di comandi simultanei. Ciò significa che l'hardware non può dedicare tutte le sue risorse a una singola coda. Pertanto, se utilizzi solo 3 di essi ... potresti perdere oltre il 50% delle tue prestazioni potenziali in risorse che l'implementazione è in attesa di utilizzare.
Concesso, l'implementazione potrebbe ridimensionare queste cose in modo dinamico. Ma a meno che non profili questo caso particolare, non lo saprai mai. Oh, e se scala dinamicamente ... allora non sarai guadagnando un sacco da usare più code come questa.
fonte
2016-06-01 17:34:26
È vero. Se stai facendo molti trasferimenti (ad esempio, i buffer di staging), specialmente in fase di esecuzione, si consiglia di utilizzare una coda di trasferimento dedicata. Con i driver recenti, le GPU NVIDIA e AMD dovrebbero offrire alle famiglie di code solo trasferimenti di supporto (o primari). –
Dovrebbe? Pensavo che lo avessero già fatto. Almeno AMD da tempo i beta driver ... E penso di averlo tratto da alcuni discorsi di NVIDIA. – krOoze
"* Sì, pensateli come core della CPU in questo senso. *" Penso che l'analogia, per le code della stessa famiglia, dia un'impressione sbagliata. Sembra che, se una GPU fornisce 16 core grafici separati e stai solo inviando il lavoro a 1 di loro, allora stai usando solo 1/16 dell'hardware della tua GPU. Sembra decisamente improbabile. Per le code di * diverse * famiglie, questa analogia ha senso. Rappresentano hardware distinto. Le code all'interno della stessa famiglia non necessariamente lo fanno. –