Durante il tentativo di migliorare le prestazioni della mia classe di rilevamento delle collisioni, ho scoperto che circa l'80% del tempo trascorso alla GPU, ha speso in condizioni if / else solo cercando di capire i limiti per i secchi attraverso i quali dovrebbe passare.
Più precisamente:
ogni thread ottiene un ID, da quell'ID recupera il suo triangolo dalla memoria (3 interi ciascuno) e da quei 3 recupera i suoi vertici (3 float ciascuno).
Quindi trasforma i vertici in punti della griglia interi (attualmente 8x8x8) e li trasforma nei limiti del triangolo su quella griglia
Per trasformare i 3 punti in limiti, trova il min / max di ogni dimensione tra ciascuno dei punti
Poiché al linguaggio di programmazione che sto usando manca un minmax intrinseco, ne ho creato uno anch'io, simile a questo:
procedure MinMax(a, b, c):
local min, max
if a > b:
max = a
min = b
else:
max = b
min = a
if c > max:
max = c
else:
if c < min:
min = c
return (min, max)
Quindi in media dovrebbe essere 2,5 * 3 * 3 = 22,5 confronti che finiscono per consumare molto più tempo rispetto ai test di intersezione triangolo - bordo effettivi (circa 100 * 11-50 istruzioni).
In effetti, ho scoperto che il pre-calcolo dei bucket richiesti sulla CPU (single threaded, nessuna vettorializzazione), impilandoli in una vista gpu insieme alla definizione del bucket e facendo fare alla gpu ~ 4 letture extra per thread era 6 volte più veloce del provare per capire i limiti sul posto. (nota che vengono ricalcolati prima di ogni esecuzione poiché ho a che fare con mesh dinamiche)
Allora, perché il confronto è così orrendamente lento su una GPU?