CUDA vs OpenCL pod koniec 2013 r

34

Jak CUDA i OpenCL porównują się ze sobą pod koniec 2013 roku z perspektywy programisty? Moja grupa myśli o próbie wykorzystania obliczeń na GPU. Czy ograniczalibyśmy się znacznie, wybierając sprzęt obsługujący tylko OpenCL, ale nie CUDA?

Aby być bardziej szczegółowym, czy poniższe założenia są prawidłowe?

  • Wszystko, co jest możliwe w CUDA, jest również możliwe w OpenCL

  • Dopóki nie korzystamy z bibliotek, dane zadanie nie jest znacznie łatwiejsze (ani trudniejsze) do wykonania w żadnej z nich

  • Główną zaletą CUDA jest dostępność bibliotek

  • Oba mają dobre wsparcie dla wszystkich trzech głównych platform (Win / OSX / Linux)

Szabolcs
źródło
1
Spróbuję zaktualizować pytanie, jeśli nie jest wystarczająco szczegółowe ... jesteśmy nowi w tej domenie i jest to jedno z podstawowych pytań, które pojawiły się, szczególnie ze względu na wybór sprzętu. Jedną rzeczą, która zwróciła moją uwagę i uczyniła mnie ostrożnym wobec OpenCL, jest ten wątek . Jeśli OpenCL nie jest wystarczająco dobry do raytracingu (Blender), to może nie jest wystarczająco dobry do HPC albo ...
Szabolcs
Nie jestem aktywny w procesorach graficznych od 2011 roku, więc dam komuś bardziej aktualną odpowiedź, ale stwierdzenie „dane zadanie nie jest znacznie łatwiejsze do wykonania w żadnym z nich” było czymś, czego nie znalazłem prawda w ogóle. Tutaj są osobiste uprzedzenia, ale czułem, że CUDA był o wiele lepszy od OpenCL pod względem łatwości programowania. Musiałbym sam siebie zaktualizować, ale gdybyś zapytał mnie 2 lata temu, powiedziałbym, że nie dotknę OpenCL 10-metrowym kijem.
Aurelius,
Mam świadomość tego pytania: Przyszłość OpenCL , ale nie jest to dokładnie to samo pytanie i ma ono 2 lata. Zakładam, że rzeczy mogą ulec zmianie za dwa lata.
Szabolcs,
Jednym z praktycznych pytań jest to, czy Mac Pro 2013 z kartami AMD FirePro jest dobry do zapoznania się i korzystania z obliczeń na GPU (brak obsługi CUDA).
Szabolcs,
Warto też zachować C ++ AMP na swoim radarze. Implementacja lvvm jest w przygotowaniu. hsafoundation.com/bringing-camp-beyond-windows-via-clang-llvm . Microsoft już utworzył biblioteki C ++ AMP dla FFT, BLAS i LAPACK.
Roger Dahl,

Odpowiedzi:

37

Spróbuję podsumować moje doświadczenia zdobyte podczas tworzenia ViennaCL, gdzie mamy backendy CUDA i OpenCL, głównie z tłumaczeniami wielu jąder obliczeniowych 1: 1. Z twojego pytania zakładam również, że głównie zajmujemy się tutaj procesorami graficznymi.

Przenośność wydajności.Po pierwsze, nie ma czegoś takiego jak jądra przenośne pod względem wydajności w tym sensie, że pisze się je raz i będzie działać wydajnie na każdym sprzęcie. Nie w OpenCL, gdzie jest to bardziej widoczne ze względu na szerszy zakres obsługiwanego sprzętu, ale także nie w CUDA. W CUDA jest to mniej widoczne ze względu na mniejszy zakres obsługiwanego sprzętu, ale nawet tutaj musimy rozróżnić co najmniej trzy architektury sprzętowe (pre-Fermi, Fermi, Kepler). Te fluktuacje wydajności mogą z łatwością spowodować 20-procentową zmienność wydajności w zależności od sposobu organizacji wątków i wybranych grup roboczych, nawet jeśli jądro jest tak proste jak kopia buforowa. Prawdopodobnie warto również wspomnieć, że na procesorach graficznych wcześniejszych niż Fermi i Fermi można było pisać szybkie jądra mnożenia macierzy i macierzy bezpośrednio w CUDA, podczas gdy w przypadku najnowszych układów GPU Keplera wydaje się, że należy przejść do języka pseudo-montażu PTX, aby zbliżyć się do wydajności CUBLAS. Tak więc wydaje się, że nawet język kontrolowany przez dostawcę, taki jak CUDA, ma problemy z nadążeniem za rozwojem sprzętu. Co więcej, cały kod CUDA jest kompilowany statycznie po uruchomieniu nvcc, co nieco wymaga równoważenia poprzez flagę -arch, podczas gdy jądra OpenCL są kompilowane w czasie wykonywania z kompilatora just-in-time, więc możesz w zasadzie dostosować jądra aż do specyfiki konkretnego urządzenia obliczeniowego. Ta ostatnia jest jednak dość zaangażowana i zwykle staje się bardzo atrakcyjną opcją w miarę dojrzewania kodu i gromadzenia doświadczeń. Cena do zapłaty to czas O (1) wymagany do kompilacji dokładnie na czas, co może być problemem w niektórych sytuacjach. OpenCL 2.

Debugowanie i profilowanie. Narzędzia do debugowania i profilowania CUDA są najlepsze dostępne dla GPGPU. Narzędzia AMD też nie są złe, ale nie zawierają klejnotów takich jak cuda-gdb czy cuda-memcheck. Ponadto, do dziś NVIDIA zapewnia najbardziej niezawodne sterowniki i zestawy SDK dla GPGPU, zawieszanie się systemu z powodu błędnych jąder jest naprawdę wyjątkiem, a nie regułą, zarówno w OpenCL, jak i CUDA. Z powodów, których prawdopodobnie nie muszę tutaj wyjaśniać, NVIDIA nie oferuje już debugowania i profilowania dla OpenCL z CUDA 5.0 i nowszymi.

Dostępność i wygoda. O wiele łatwiej jest uruchomić pierwsze kody CUDA, zwłaszcza że kod CUDA dość dobrze integruje się z kodem hosta. (Cena omówię później). W Internecie jest wiele samouczków, a także przewodniki po optymalizacji i niektóre biblioteki. Z OpenCL musisz przejść sporo kodu inicjującego i napisać jądra w ciągach, więc błędy kompilacji znajdziesz tylko podczas wykonywania, gdy podajesz źródła do kompilatora jit. Zatem przejście przez jeden cykl kodu / kompilacji / debugowania w OpenCL zajmuje więcej czasu, więc produktywność jest zwykle niższa na tym początkowym etapie programowania.

Aspekty biblioteki oprogramowania. Podczas gdy poprzednie elementy były na korzyść CUDA, integracja z innym oprogramowaniem jest dużym plusem dla OpenCL. Możesz użyć OpenCL po prostu łącząc się ze wspólną biblioteką OpenCL i to wszystko, podczas gdy w CUDA musisz mieć cały łańcuch narzędzi CUDA dostępny. Co gorsza, aby nvcc działało, musisz użyć poprawnych kompilatorów hosta. Jeśli kiedykolwiek próbowałeś użyć np. CUDA 4.2 z GCC 4.6 lub nowszą wersją, ciężko Ci będzie pracować. Zasadniczo, jeśli zdarzy się, że używasz kompilatora nowszego niż CUDA SDK, mogą wystąpić problemy. Integracja z systemami kompilacji, takimi jak CMake, jest kolejnym źródłem bólu głowy (można również znaleźć wiele dowodów na np. PETSclisty mailingowe). To może nie być problem na twoim komputerze, na którym masz pełną kontrolę, ale jak tylko rozpowszechnisz swój kod, napotkasz sytuacje, w których użytkownicy są nieco ograniczeni w stosie oprogramowania. Innymi słowy, dzięki CUDA nie możesz już wybierać swojego ulubionego kompilatora hosta, ale NVIDIA decyduje, które kompilatory możesz używać.

Inne aspekty. CUDA jest trochę bliżej sprzętu (np. Wypaczenia), ale moje doświadczenie z algebrą liniową jest takie, że rzadko uzyskuje się z tego znaczącą korzyść. Istnieje jeszcze kilka bibliotek oprogramowania dla CUDA, ale coraz więcej bibliotek korzysta z wielu backendów obliczeniowych. Tymczasem ViennaCL , VexCL lub Paralution obsługują backendy OpenCL i CUDA, podobny trend można zaobserwować w przypadku bibliotek w innych obszarach.

GPGPU nie jest srebrną kulą. Wykazano, że GPGPU zapewnia dobrą wydajność dla operacji ustrukturyzowanych i zadań o ograniczonej mocy obliczeniowej. Jednak w przypadku algorytmów z niemałym udziałem przetwarzania sekwencyjnego GPGPU nie może magicznie pokonać Prawa Amdahla . W takich sytuacjach lepiej jest zastosować dobrą implementację procesora najlepszego dostępnego algorytmu niż próbować rzucić równoległy, ale mniej odpowiedni algorytm na swój problem. Ponadto PCI-Express jest poważnym wąskim gardłem, dlatego należy wcześniej sprawdzić, czy oszczędności wynikające z GPU mogą zrekompensować obciążenie związane z przenoszeniem danych tam i z powrotem.

Moja rekomendacja. Proszę wziąć pod uwagę CUDA i OpenCL zamiast CUDA lubOpenCL. Nie trzeba niepotrzebnie ograniczać się do jednej platformy, ale zamiast tego wyciągnąć to, co najlepsze z obu światów. Dla mnie najlepsze jest skonfigurowanie początkowej implementacji w CUDA, debugowanie, profilowanie, a następnie przeniesienie jej do OpenCL za pomocą prostych podstawień łańcuchów. (Możesz nawet sparametryzować swoje procedury generowania łańcucha jądra OpenCL, aby mieć pewną elastyczność w dostosowywaniu do docelowego sprzętu.) Ten wysiłek związany z przenoszeniem zwykle zajmuje mniej niż 10 procent twojego czasu, ale daje ci również możliwość działania na innym sprzęcie. Możesz być zaskoczony, jak dobrze sprzęt inny niż NVIDIA może działać w określonych sytuacjach. Przede wszystkim rozważ ponowne wykorzystanie funkcjonalności w bibliotekach w możliwie największym stopniu. Podczas gdy szybki i brudna ponowna implementacja niektórych funkcji często działa akceptowalnie w przypadku wykonywania jednowątkowego na procesorze, często daje słabą wydajność na bardzo równoległym sprzęcie. Idealnie możesz nawet przenieść wszystko do bibliotek i nigdy nie musisz się martwić, czy używają CUDA, OpenCL, czy obu z nich wewnętrznie. Osobiście nigdy nie odważyłbym się napisać kodu zablokowanego przez dostawcę dla czegoś, na czym chcę polegać za kilka lat, ale ten aspekt ideologiczny powinien zostać omówiony osobno.

Karl Rupp
źródło
Co sądzisz o aktualnej wydajności i użyteczności standardowego FFT 1D, 2D, 3D na obu platformach?
unsym
Jeśli chodzi o kompilację JIT, CUDA oferuje również taką możliwość , ale z pewnymi ograniczeniami.
BenC,
@hwlau: FFT to standardowa funkcjonalność bibliotek dostawców, więc jest całkiem niezależna od CUDA vs. OpenCL.
Karl Rupp,
@BenC: Ograniczenia są rzeczywiście bardzo poważne, jest to jedynie specjalizacja wstępnie skompilowanych jąder CUDA do podstawowego sprzętu.
Karl Rupp,
1
Czy masz jakieś uwagi na temat tego potencjalnego problemu ? Nie jest dla mnie jasne, czy jest to problem ze sprzętem AMD, czy z samym OpenCL (tj. Czy problem nie występuje w OpenCL na NVIDIA). Być może nie jest to problem w większości naukowych aplikacji komputerowych, ponieważ są one zwykle mniejsze i mniej złożone niż zaawansowany raytracer? BTW dziękuję za świetną odpowiedź!
Szabolcs,