Optymalny dostęp do pamięci podczas korzystania z tabel odnośników na GPU?

9

Badam algorytmy izosurface na GPU dla projektu licencjata (w szczególności koncentrując się na binarnych danych wokseli we / wy, a nie na polach o wartości rzeczywistej). Mam więc implementację procesora starych, dobrych, marszowych kostek uruchomioną w OpenFrameworks, a teraz na etapie próby przeniesienia jej do shaderów obliczeniowych GLSL i rozważenia pułapek przed zanurzeniem się. Napisałem tylko shadery vert i frag wcześniej, więc jest to dla mnie zupełnie nowe.

Mój pierwszy problem polega na tym, jak efektywnie korzystać z tabeli odnośników w kilkudziesięciu lub setkach wątków w grupie roboczej? Rozumiem, że procesor graficzny ma różne rodzaje pamięci do różnych zadań, ale nie jestem całkowicie pewien, jak działa każdy z nich lub jakiego typu użyć.

Klasyczna tabela Copypasta Paula Bourke'a to tablica 256 * 16, więc jeśli używasz bajtu skalarnego, prawdopodobnie można go zapakować w teksturę 4kb lub SSBO.

Pytanie brzmi: jak powstrzymać potknięcia się różnych wątków? Wiele kostek w każdej grupie roboczej może potencjalnie mieć tę samą konfigurację, dlatego też próbuje uzyskać dostęp do tej samej lokalizacji w buforze w tym samym czasie. Czy istnieje obejście lub optymalizacja, aby sobie z tym poradzić?

Russ
źródło
Jeśli jest to tabela odnośników tylko do odczytu, możesz po prostu użyć bufora / tekstury. Możesz albo spakować go do jednego z normalnych formatów tekstur, albo możesz użyć niektórych z nowszych funkcji DX11 / OpenGL, aby mieć niestandardowy format. UAV na ziemi DX11 lub tekstura / shader_image_load_store na ziemi OpenGL.
RichieSams
Ponadto spójrz na tę prezentację: cvg.ethz.ch/teaching/2011spring/gpgpu/cuda_memory.pdf To jest dla CUDA, ale powinno dać ci lepsze wyobrażenie o tym, co dzieje się na bazowym sprzęcie
RichieSams
Nie pełna odpowiedź, ale im mniej pamięci używasz, tym lepiej, ponieważ będzie bardziej prawdopodobne, że zmieści się w pamięciach podręcznych i będzie mniej błędów pamięci podręcznej. Jeśli masz interpolowalne wartości, takie jak wypalanie punktów na krzywej do tekstur, możesz to sprawdzić jako sposób na uzyskanie tabel wyszukiwania krzywych o wyższej jakości przy mniejszej ilości pamięci: blog.demofox.org/2016/02/22/...
Alan Wolfe

Odpowiedzi:

6

Najlepsze miejsce na tablicę przeglądową dla modułu cieniującego GPU zależy od wielkości tablicy przeglądowej oraz częstotliwości / spójności dostępu. W twoim przypadku (wspominałeś 4kb) współużytkowana pamięć lokalna byłaby prawdopodobnie najlepsza (zakładając, że nie potrzebujesz tej pamięci do innych celów w tym samym jądrze). Ta pamięć ma różne nazwy w różnych interfejsach API, ale jest to ta sama architektura i jest zgodna z tymi samymi wytycznymi dotyczącymi wydajności:

  • CUDA: pamięć współdzielona grupy wątków
  • DirectCompute: pamięć współdzielona przez grupę
  • OpenCL: pamięć lokalna
  • Metal: pamięć grupy wątków
  • OpenGL: pamięć współdzielona

Przechowywanie tabeli odnośników w pamięci globalnej jako bufora tylko do odczytu może działać równie dobrze, w zależności od wielkości pamięci podręcznej konkretnego procesora graficznego, na którym pracujesz.

Zauważ, że przypuszczam, że jest to tabela odnośników tylko do odczytu. Tablica przeglądowa do odczytu i zapisu to zupełnie inna bestia i nie ma tam żadnych dobrych opcji.

GroverManheim
źródło
Istnieją również przypadki, w których bufor tylko do odczytu będzie lepszy niż przechowywanie 4kb danych tylko do odczytu we współużytkowanej pamięci lokalnej. Na przykład przechowywanie go w pamięci lokalnej może oznaczać, że dla każdej grupy wątków istnieje unikalna kopia danych. Jeśli bufor mieści się w pamięci podręcznej, całkiem możliwe, że pamięć podręczna działa lepiej niż pamięć lokalna dla wzorców dostępu tylko do odczytu.
John Calsbeek,
Dzięki za opinie. Skończyłem projekt, z którego korzystałem na razie, i skończyłem na użyciu tylko bufora teksturowego r8ui, który działał całkiem nieźle :)
Russ