2013-06-13 35 views
7

Projektuję zestaw funkcji matematycznych i implementuję je w wersjach zarówno CPU, jak i GPU (z CUDA).Pamięć CUDA do tablic przeglądowych

Niektóre z tych funkcji są oparte na tabelach odnośników. Większość stołów zajmuje 4KB, niektóre nieco więcej. Funkcje oparte na tabelach odnośników pobierają dane wejściowe, wybierają jeden lub dwa wpisy tabeli odnośników, a następnie obliczają wynik przez interpolację lub zastosowanie podobnych technik.

Moje pytanie brzmi teraz: gdzie powinienem zapisać te tabele odnośników? Urządzenie CUDA ma wiele miejsc do przechowywania wartości (pamięć globalna, stała pamięć, pamięć tekstur, ...). Pod warunkiem, że każda tabela może być odczytywana jednocześnie przez wiele wątków i że wartości wejściowe, a zatem i indeksy odnośników, mogą być całkowicie nieskorelowane pomiędzy wątkami każdej osnowy (powodując nieskorelowane dostępy do pamięci), która pamięć zapewnia najszybszy dostęp?

Dodam, że zawartość tych tabel jest wstępnie obliczona i całkowicie stała.

EDIT

prostu do wyjaśnienia: muszę przechowywać około 10 różnych tabel 4KB odnośników. W każdym razie byłoby wspaniale wiedzieć, że rozwiązanie jest takie samo jak w przypadku z np. 100 tabel 4KB lub np. 10 tabel wyszukiwania 16 KB.

+4

Stała pamięć podręczna jest przeznaczona dla przypadku rozgłoszeniowego, tj. Dostęp przez osnowę jest jednolity. Będzie działać, jeśli wszystkie wątki w warpie uzyskają dostęp do różnych lokalizacji, ale wydajność spada. Pamięć współdzielona jest szybka i ma rozmiar 48 KB, więc jest dobrze dopasowana, ale może być potrzebna do innych celów lub twój kod jest częścią biblioteki, w której to nie działa dobrze. Jeśli nie możesz używać pamięci współdzielonej, proponuję tekstury. Najlepiej nie używać żadnych tabel na GPU (zobacz także bibliotekę matematyczną CUDA), ponieważ FLOPS rosną szybciej niż przepustowość pamięci w procesorach GPU. – njuffa

+0

Dzięki, njuffa, za jasne wyjaśnienie. Moje jedyne pytanie dotyczy wspólnej pamięci. Jeśli dobrze pamiętam, pamięć ta jest dzielona między wątki w tej samej osnowie. Czy powinienem powielać moje tabele na wszystkich osnowach? Czy tabele będą trwałe po zakończeniu jądra? – Spiros

+2

Pamięć współdzielona jest dzielona między wszystkie wątki w bloku wątków. Tak więc obawiam się, że w sumie 40KB pamięci podręcznej Twój kod będzie ograniczony do pojedynczego bloku wątków na SM.W większości przypadków lepiej jest mieć uruchomione co najmniej dwa bloki wątków, więc warto rozważyć zastosowanie mieszanego schematu, w którym niektóre tabele są przechowywane w pamięci współdzielonej (te z największymi dostępami) i inne w pamięci tekstury. Pamięć tekstur ma także tę zaletę, że można uzyskać liniową interpolację (o niskiej dokładności) za darmo. Jakie funkcje matematyczne implementujesz, które wymagają dużych tabel? – njuffa

Odpowiedz

2

Pamięć tekstur (nazywana teraz pamięcią podręczną danych tylko do odczytu) byłaby prawdopodobnie wyborem wartym poznania, choć nie z powodu korzyści wynikających z interpolacji. Obsługuje 32-bitowe odczyty bez czytania powyżej tej kwoty. Łącznie ograniczasz się do 48 KB. Dla Keplera (obliczenie 3.x) jest to teraz dość łatwe do zaprogramowania.

Pamięć globalna, o ile nie zostanie skonfigurowana w trybie 32-bitowym, będzie często przeciągać po 128 bajtów dla każdego wątku, znacznie zwiększając to, co faktycznie jest potrzebne z pamięci, ponieważ (widocznie) nie można połączyć dostępu do pamięci. Tak więc tryb 32-bitowy jest prawdopodobnie tym, czego potrzebujesz, jeśli chcesz użyć więcej niż 48K (wspomniałeś 40K).

Myśląc o koalescencji, jeśli miałbyś uzyskać dostęp do zestawu wartości szeregowo z tych tabel, możesz być w stanie przeplatać tabele tak, że te kombinacje mogą być pogrupowane i odczytane jako 64 lub 128-bitowy odczyt na wątek. Oznaczałoby to, że 128 bajtów odczytanych z pamięci globalnej może być przydatne.

Problem polega na tym, że ograniczasz przepustowość pamięci rozwiązania za pomocą tabel wyszukiwania. Zmiana wielkości pamięci podręcznej L1 (w Fermi/Compute 2.x) na 48K prawdopodobnie spowoduje znaczącą różnicę, szczególnie jeśli nie korzystasz z innych 32K pamięci współdzielonej. Wypróbuj pamięć tekstur, a następnie pamięć globalną w trybie 32-bitowym i zobacz, która z nich działa najlepiej dla twojego algorytmu. Na koniec wybierz kartę o dobrej przepustowości pamięci, jeśli masz wybór ponad sprzęt.