Wydajność pętli w module cieniującym

11

Zastanawiam się, jaki jest najlepszy sposób zintegrowania funkcji pętli dynamicznej w module cieniującym?

Po pierwsze, wydaje się, że tablice dynamiczne nie są możliwe. Czy zatem lepiej jest utworzyć tablicę o maksymalnym rozmiarze i wypełnić tylko jej część lub zdefiniować tablice o zdefiniowanych rozmiarach?

Więc jaki jest najlepszy sposób na iterację tej tablicy?

Czy lepiej jest użyć rozwiniętej pętli lub pętli dynamicznej dla czegoś od 4 do 128 iteracji? Widziałem również, że można rozwinąć go do maksymalnej z góry określonej liczby iteracji, a następnie zatrzymać go z warunkiem, takim jak if (i == myCurrentMaximumIterationNumber).

Mata
źródło
2
Co próbujesz zrobić z tablicą i pętlą? Pytam, bo to dla mnie brzmi jak problem XY . Ponieważ najlepszym sposobem na użycie warunków i pętli na GPU jest powstrzymanie się od ich używania, być może istnieją jeszcze lepsze sposoby zamiast używania tablic i pętli w twoim przypadku.
Nero
Realizuję efekt rozpraszania podpowierzchni ekranu ekranowego, który obecnie działa. Ale mam wątpliwości co do sposobu, w jaki używam jądra zgodnie z wydajnością. Zdecydowałem się zrobić maksymalny rozmiar tablicy i wypełnić tylko część i użyć dynamicznej pętli z dynamiczną liczbą iteracji, która jest związana z aktualnie używaną zawartością tablicy. Myślę, że są rzeczy do zrobienia lub wiedzieć, na przykład programując shadery według wydajności. Moim zdaniem, pętle są częstym tematem dotyczącym wydajności, który może być zgodny z pewnymi zasadami i być może „dobrymi praktykami”, ale nie znalazłem na to żadnej dobrej odpowiedzi.
MaT,

Odpowiedzi:

6

Kompilatory modułu cieniującego są bardzo agresywne przy rozwijaniu, ponieważ wczesny sprzęt często nie miał kontroli przepływu, a koszt nowszego sprzętu może się różnić. Jeśli masz test porównawczy, na którym aktywnie testujesz, oraz szereg odpowiedniego sprzętu, spróbuj tego, co się stanie. Twoja pętla dynamiczna jest bardziej podatna na interwencję programisty niż pętla statyczna - ale pozostawienie jej kompilatorowi jest nadal dobrą radą, chyba że masz dostępny test porównawczy. Po przeprowadzeniu testu eksploracja jest warta (i przyjemna).

BTW, największą stratą z dynamiczną pętlą na GPU jest to, że poszczególne „wątki” w froncie / warpie zakończą się w różnych momentach. Wątki, które zatrzymują się później, zmuszają wszystkie, które kończą się wcześniej, do wykonywania NOP.

Zagnieżdżone pętle należy dokładnie przemyśleć: zaimplementowałem oparty na blokach dekoder entropii, który kodował bieg zer (dla kompresji podobnej do JPEG). Naturalną implementacją było odkodowanie przebiegów w ciasnej pętli wewnętrznej - co oznaczało, że często tylko jeden wątek robił postępy; spłaszczając pętlę i jawnie testując w każdym wątku, czy aktualnie dekoduje przebieg, czy nie, utrzymałem wszystkie wątki aktywne w pętli o stałej długości (wszystkie dekodowane bloki miały ten sam rozmiar). Gdyby wątki były jak wątki procesora, zmiana byłaby okropna, ale na GPU, na którym pracowałem, uzyskałem 6-krotny wzrost wydajności (co było nadal okropne - nie było wystarczającej liczby bloków, aby utrzymać zajętość GPU - ale to był dowód koncepcji).

Daniel M. Gessel
źródło