2013-09-01 28 views
5

Szukam wysokiej wydajności sumy multiscan/multi prefix-sum (wiele wierszy w jednym wykonaniu jądra) dla mojego projektu w CUDA.Funkcja sumowania/skanowania prefiksu o wysokiej wydajności w CUDA, szukanie ciągu, zmiana biblioteki cuDPP

Próbowałem tej z biblioteki Thrust, ale jest zbyt powolny. Również zawiesza się po kompilacji flagami debugowania nvcc (-g-G).

Po moim niepowodzeniu z Thrust skupiłem się na bibliotece cuDPP, która kiedyś była częścią zestawu narzędzi CUDA. Wydajność cuDPP jest naprawdę dobra, ale biblioteka nie jest aktualna z najnowszą cuda 5.5 i są pewne globalne problemy z naruszeniem pamięci w funkcji cudppMultiScan() podczas debugowania za pomocą modułu sprawdzania pamięci. (cuda 5.5, nsight 3.1, visual studio 2010, gtx 260 cc 1.3)

Czy ktoś ma pojęcie, czego używać zamiast tych dwóch bibliotek?

R.

+0

Czy obejrzałeś [ArrayFire] (http://accelereyes.com/arrayfire), nad którym pracujemy w AccelerEyes? – arrayfire

+0

Nie, nie widziałem tego wcześniej, wygląda całkiem interesująco! dzięki! :) co z jego wydajnością? Czy jest to biblioteka bardziej wydajna lub zorientowana na wydajność? – user1946472

+0

Jeśli chcesz użyć narzędzia Thrust do zeskanowania wierszy macierzy, nie wywołuj wielokrotnie frazy "inclusive_scan". Przypisanie każdego wiersza indeksu i użycie 'inclusive_scan_by_key'. Możesz dostosować ten [przykład] (https://github.com/thrust/thrust/blob/master/examples/sum_rows.cu). –

Odpowiedz

2

tych bibliotek, szczególnie nacisk, starają się być jak rodzajowy, jak to możliwe i często wymaga optymalizacji specjalizacji: Na przykład specjalizacji algorytmu mogą korzystać z pamięci współdzielonej podstawowych typów (jak int lub float), ale wersja ogólna nie może. Zdarza się, że w danej sytuacji brakuje specjalizacji!

Warto używać tych dobrze przetestowanych bibliotek generycznych w jak największym stopniu, ale czasami, w przypadku niektórych sekcji o krytycznym znaczeniu wydajnościowym, można rozważyć własną implementację.

W twojej sytuacji potrzebujesz wielu skanów równolegle dla różnych wierszy. Dobra implementacja nie uruchamiałaby skanowania osobno dla różnych wierszy: miałoby to samo wywołanie jądra uruchomione jednocześnie dla wszystkich elementów wszystkich wierszy. W zależności od indeksu wątek może wiedzieć, który wiersz przetwarza i zignoruje wszystkie dane z wiersza.

Taka specjalizacja wymaga funktora, który zwraca wartość pochłaniającą, która uniemożliwia mieszanie wierszy. Jednak twoja własna ostrożna implementacja prawdopodobnie byłaby szybsza.

2

Aby napisać własny skanowanie prefiksu, można odwołać się do

  1. przykładzie skanowania CUDA SDK;
  2. Rozdział 13 N. Wilt, "Podręcznik CUDA";
  3. Rozdział 6 programu Cook, "Programowanie CUDA, przewodnik programisty do obliczeń równoległych z procesorami graficznymi";
  4. .

Aby zrobić wielu prefix-sumę można uruchomić wiele razy tego samego jądra (jak sugeruje a.lasram) lub starać się osiągnąć cuncurrency strumieniami CUDA, chociaż ja nie wiem będzie to działać skutecznie na karcie .

+0

Używanie strumieni jest świetnym pomysłem, ale myślę, że jeszcze lepiej jest uruchomić pojedyncze jądro, w którym każdy wątek "zacieśni" obliczenia w jednym wybranym wierszu. –

+0

Mam 231 wierszy z 1424 zmiennymi, więc wykonanie każdego wiersza w osobnym jądrze daje zbyt duży czas obciążenie spowodowane przez cudalaunch. cuDPP wykonuje to zadanie w około 0,11 ms na moim komputerze (gtx260), co jest dla mnie doskonałym wynikiem! W przypadku wydajności cuDPP lib jest doskonały. Na razie spróbuję biblioteki arrayFire zasugerowanej przez @ accelereyes. Dziękuję za Twoją odpowiedź. – user1946472