Ciąg do programowania GPU


10

Jestem bardzo nowy w programowaniu GPGPU, więc proszę wybacz mi, jeśli pytanie nie jest szczególnie odpowiednie. Z tego, co rozumiem, programowanie na GPU to bardzo skomplikowana praca inżynierska w porównaniu do zwykłego programowania procesora. Należy bardzo uważać na problemy z rozbieżnościami, kafelkami, przypiętą pamięcią i nakładaniem się komunikacji host-urządzenie / obliczanie urządzenia.

Po przeprowadzeniu drobnych badań znalazłem bibliotekę ciągu, która wydaje się próbować naśladować C ++ STL. To jest całkiem miłe. Jednak w oparciu o moje bardzo ograniczone doświadczenie i widziałem wszystkie mikro-zarządzanie wymagane do uzyskania dobrej wydajności, jestem nieco sceptyczny co do wydajności. Czy ciąg może skutecznie obsługiwać wewnętrznie wszystkie skomplikowane elementy programowania? Niektóre bardzo dobrze znane biblioteki, takie jak PETSc, wydają się korzystać z tego pakietu, co sprawia, że ​​wierzę, że powinien.

Zastanawiałem się, czy ludzie z większym doświadczeniem w CUDA i ciągłości mogliby powiedzieć kilka słów na temat wydajności pakietu w porównaniu do programowania na niskim poziomie CUDA. Kiedy mogę użyć ciągu i kiedy powinienem wrócić do CUDA?


Czy rozważałeś ArrayFire?
arrayfire,

Odpowiedzi:


2

Nie mam osobistego doświadczenia z ciągiem, ale używam ViennaCL, kolejnej wysokopoziomowej biblioteki GPU, która ukrywa prawie wszystkie szczegóły. Z mojego osobistego testu porównawczego widzę przyspieszenie 2x - 40x w rzeczywistym obliczeniu, jeśli zignorujesz czas potrzebny na poruszanie się po pamięci.

Kiedy powinieneś używać procesora vs. ciąg w porównaniu z CUDA wszystko zależy od rozwiązywanego problemu, twoich umiejętności i dostępnego czasu. Poleciłbym zacząć od rozwiązania prostych problemów za pomocą wszystkich 3 metod, aby zobaczyć ich względną wydajność. Następnie możesz napisać swoje oprogramowanie w szybki sposób, przetestować go i zastosować odpowiednią metodę GPU w obszarach, które wymagają przyspieszenia, zamiast marnować czas na pisanie oprogramowania CUDA, które da ci tylko kilka minut czasu na wykonanie .


To ma dla mnie idealny sens. Zawsze trzeba się najpierw profilować. Tak więc w twoim przykładzie przyspieszenie uzyskałeś dzięki użyciu ViennaCL. Czy próbowałeś bezpośrednio OpenCL, aby sprawdzić różnicę?
mmirzadeh

Nie, podobnie jak ty, jestem nowy w obliczeniach na GPU. W ciągu najbliższego roku lub dwóch planuję powoli poszerzać swoje umiejętności o CUDA i OpenCL, ale obecnie korzystam tylko z biblioteki. Dokumentacja ViennaCL stwierdza, że ​​dalsze przyspieszenie byłoby możliwe dzięki dostrajanej implementacji openCL, która prawdopodobnie byłaby rzędu innego 2x-10x, jednak dowiedziałem się, że przepustowość pamięci to 900-kilogramowy goryl w pokoju, który naprawdę określa twoją wydajność.
Godric Seer,

5

Użyłem Thrust w moim projekcie rozbudowy klastra. W zależności od sytuacji Thrust może działać równie dobrze lub lepiej niż implementacja niskiego poziomu, którą sam rzucisz (w szczególności reducejądro działa dla mnie całkiem dobrze). Jednak ogólna natura i elastyczność Thrust oznacza, że ​​czasami musi wykonać wiele dodatkowych operacji kopiowania, wypełniania tablic itp., Co może spowolnić go w kilku paskudnych przypadkach. Ostatni raz korzystałem z sortniego dość wolno w porównaniu do innych bibliotek, takich jak b40c lub mgpu. Jednak NVIDIA pracuje nad poprawą wydajności algorytmicznej Thrust, więc może to być mniejszy problem w przyszłości.

Powinieneś spróbować napisać kod, używając zarówno Thrust, jak i CUDA, a następnie używając Visual Profilera, aby określić, który jest lepszy dla konkretnego zadania, które Cię interesuje. Jeśli jest prawdopodobne, że transfer pamięci zajmie najwięcej czasu działania twojego programu, a ty nie nie chcę się martwić optymalizacją własnych jąder pod kątem konfliktów bankowych, liczby instrukcji itp., wtedy użyłbym Thrust. Ma także tę dodatkową zaletę, że sprawia, że ​​Twój kod jest mniej szczegółowy i łatwiejszy do odczytania dla osób, które nie są zaznajomione z programowaniem GPU.


3

Celem ciągu (jak większość bibliotek szablonów) jest zapewnienie abstrakcji na wysokim poziomie, przy jednoczesnym zachowaniu dobrej, a nawet doskonałej wydajności.

Sugerowałbym, aby nie martwić się zbytnio wydajnością, ale zadać sobie pytanie, czy

  • twoja aplikacja może być opisana w kategoriach algorytmów implementowanych w ciągu i jeśli

  • podoba ci się możliwość pisania „ogólnego” kodu równoległego, bez potrzeby wchodzenia w krwawe szczegóły dotyczące znalezienia skutecznego mapowania na daną architekturę sprzętową / programową.

Jeśli odpowiesz pozytywnie na oba pytania, powinieneś być w stanie wdrożyć swój program przy mniejszym wysiłku w odniesieniu do implementacji tylko CUDA. Następnie możesz profilować swoją aplikację i zdecydować, czy warto spróbować poprawić wydajność.

To powiedziawszy, muszę wyznać, że nie lubię programowania „ogólnego”, ponieważ jestem gotów nauczyć się czegoś nowego, gdy piszę program. Podążę inną drogą: napisz prototypową implementację w python + numpy + scipy, a następnie dodaj jądra CUDA dla tych 1% - 2% kodu, który naprawdę wymaga optymalizacji i jest odpowiedni do uruchomienia na GPU. Oczywiście, robiąc to, potrzebujesz pewnego rodzaju wiedzy wstępnej, ponieważ zła decyzja w fazie prototypowania (np. Struktura danych nieodpowiednia dla jąder CUDA) może mieć straszne wyniki w zakresie wydajności. Zwykle potrzeba więcej iteracji, aby uzyskać dobry kod i nie ma pewności, że będzie lepiej niż ciąg.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.