Намагаючись покращити продуктивність мого класу виявлення зіткнень, я виявив, що ~ 80% часу, витраченого на gpu, він витратив на умови if / else, просто намагаючись з'ясувати межі для відра, через який він повинен пройти цикл.
Точніше:
кожен потік отримує ідентифікатор, за допомогою цього ідентифікатора він отримує свій трикутник із пам'яті (по 3 цілих числа кожен), а за допомогою цих 3 він отримує вершини (3 поплавця в кожній).
Потім він перетворює вершини в цілі точки сітки (в даний час 8x8x8) і перетворює їх у трикутні межі на цій сітці
Щоб перетворити 3 точки в межі, він знаходить min / max кожного виміру серед кожної з точок
Оскільки в мові програмування, яку я використовую, відсутня властива minmax, я зробив її сам, виглядає так:
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)
Таким чином, в середньому це повинно бути 2,5 * 3 * 3 = 22,5 порівняння, що закінчується їжею набагато більше часу, ніж фактичні тести на перетину трикутника - краю (приблизно 100 * 11-50 інструкцій).
Насправді я виявив, що попередній обчислення необхідних відро на процесорі (однопотокова, без векторизації), складання їх у подання gpu разом із визначенням відра і надання gpu робити ~ 4 додаткових читання на один потік було в 6 разів швидше, ніж спроба щоб вияснити межі на місці. (зауважте, що вони перераховуються перед кожним виконанням, оскільки я маю справу з динамічними сітками)
То чому порівняння настільки жахливо повільне на gpu?