[performance] La divergenza delle filiali è davvero così grave?



Answers

Question

Ho visto molte domande sparse su Internet sulla divergenza delle filiali e su come evitarlo . Tuttavia, anche dopo aver letto dozzine di articoli su come funziona CUDA, non riesco a vedere come evitare la divergenza delle filiali nella maggior parte dei casi . Prima che qualcuno mi salti addosso con le unghie aperte, permettimi di descrivere ciò che considero essere "la maggior parte dei casi".

Mi sembra che la maggior parte delle istanze di divergenza delle filiali coinvolga un numero di blocchi di codice veramente distinti. Ad esempio, abbiamo il seguente scenario:

if (A):
  foo(A)
else:
  bar(B)

Se abbiamo due thread che incontrano questa divergenza, il thread 1 verrà eseguito per primo, prendendo il percorso A. Successivamente, il thread 2 prenderà il percorso B. Per rimuovere la divergenza, potremmo cambiare il blocco sopra in modo da leggere in questo modo:

foo(A)
bar(B)

Supponendo che sia sicuro chiamare foo(A) sul thread 2 e bar(B) sul thread 1, ci si potrebbe aspettare che le prestazioni migliorino. Tuttavia, ecco come vedo io:

Nel primo caso, i thread 1 e 2 vengono eseguiti in serie. Chiama questi due cicli di clock.

Nel secondo caso, i thread 1 e 2 eseguono foo(A) in parallelo, quindi eseguono la bar(B) in parallelo. Questo mi sembra ancora come due cicli di clock, la differenza è che nel primo caso, se foo(A) implica una lettura dalla memoria, immagino che il thread 2 possa iniziare l'esecuzione durante quella latenza, il che si traduce in latenza nascosta. Se questo è il caso, il codice divergente del ramo è più veloce.




Links