Kiedy powinienem odciążyć pracę do GPU zamiast procesora?

16

Powstają nowsze systemy, takie jak OpenCL , abyśmy mogli uruchamiać coraz więcej kodu na naszych procesorach graficznych, co ma sens, ponieważ powinniśmy być w stanie wykorzystać jak najwięcej mocy w naszych systemach.

Jednak w przypadku wszystkich tych nowych systemów wydaje się, że procesory graficzne są lepsze pod każdym względem od procesorów . Ponieważ procesory graficzne mogą wykonywać obliczenia równoległe, procesory wielordzeniowe wydają się być znacznie lepsze niż procesory wielordzeniowe; będziesz w stanie wykonać wiele obliczeń jednocześnie i naprawdę poprawić prędkość. Czy nadal istnieją pewne przypadki, w których przetwarzanie szeregowe jest jeszcze lepsze, szybsze i / lub bardziej wydajne niż równoległe?

RetroX
źródło
6
Naprawdę nie pytanie o sprzęt. Należy przeredagować na „kiedy programowanie procesora (-ów) jest lepsze niż programowanie GPU (-ów)” i czy takie jest całkiem dobre pytanie p.se IMO. Zobacz tag GPGPU między innymi w SO. Ale pytania o architekturę „Jakiej technologii użyć” są tutaj lepsze niż tam.
Kate Gregory,
1
@Kate Ten kąt wydaje się być bardzo dobrze uwzględniony w powiązanym pytaniu Super User. Czytając to, jestem trochę zaskoczony, że nie został tutaj migrowany, szczerze mówiąc. Jest też to na SO. Ponownie otworzę pytanie (skoro masz rację, aspekty programowania są tutaj na temat). Mam nadzieję, że widzimy odpowiedź, która nie tylko wskazuje na istniejące (doskonałe) pokrycie tego problemu.
Adam Lear
1
Do punktu @ Anny, myślę, że odpowiedzi powinny dotyczyć raczej tego, kiedy programista powinien użyć GPU, a nie czysto teoretycznej dyskusji na temat różnicy między GPU a CPU. Zredagowałem tytuł, aby to odzwierciedlić.
2
@RetroX Nie możemy zamykać pytań jako duplikatów, jeśli znajdują się w różnych witrynach.
Adam Lear

Odpowiedzi:

27

Jednak w przypadku wszystkich tych nowych systemów wydaje się, że procesory graficzne są lepsze pod każdym względem od procesorów.

Jest to fundamentalne nieporozumienie. Obecne rdzenie GPU są nadal ograniczone w porównaniu z obecnymi procesorami najwyższej klasy. Myślę, że architektura Fermi firmy NVIDIA jest najmocniejszym obecnie dostępnym układem GPU. Ma tylko 32-bitowe rejestry arytmetyki liczb całkowitych, a także mniejszą zdolność przewidywania gałęzi i wykonywania spekulatywnego niż obecny towarowy procesor Intel. Układy Intel i7 zapewniają trzy poziomy buforowania, rdzenie Fermi mają tylko dwa, a każda pamięć podręczna na Fermi jest mniejsza niż odpowiednia pamięć podręczna na i7. Komunikacja między procesami między rdzeniami GPU jest dość ograniczona, a obliczenia muszą być uporządkowane, aby uwzględnić to ograniczenie (rdzenie są podzielone na bloki, a komunikacja między rdzeniami w bloku jest stosunkowo szybka, ale komunikacja między blokami jest powolna).

Znaczącym ograniczeniem obecnych GPU jest to, że wszystkie rdzenie muszą mieć ten sam kod. W przeciwieństwie do rdzeni procesora, nie można powiedzieć jednemu rdzeniu GPU, aby uruchomił klienta poczty e-mail, a drugiemu, aby uruchomić serwer WWW. Dajesz GPU funkcję odwracania macierzy, a wszystkie rdzenie wykonują tę funkcję na różnych bitach danych.

Procesory na GPU żyją w odizolowanym świecie. Mogą kontrolować wyświetlacz, ale nie mają dostępu do dysku, sieci ani klawiatury.

Dostęp do systemu GPU wiąże się z dużymi kosztami ogólnymi. GPU ma własną pamięć, więc twoje obliczenia będą ograniczone do ilości pamięci na karcie GPU. Przesyłanie danych między pamięcią GPU a pamięcią główną jest stosunkowo drogie. Pragmatycznie oznacza to, że nie ma żadnej korzyści z przekazania garści krótkich obliczeń z procesora do GPU, ponieważ koszty konfiguracji i porzucenia skracają czas potrzebny na wykonanie obliczeń.

Najważniejsze jest to, że procesory graficzne są przydatne, gdy masz wiele (jak w setkach lub tysiącach) kopii długich obliczeń, które można obliczać równolegle. Typowe zadania, dla których jest to powszechne, to obliczenia naukowe, kodowanie wideo i renderowanie obrazów. W przypadku aplikacji takich jak edytor tekstu jedyną funkcją, w której GPU może być przydatny, jest renderowanie typu na ekranie.

Charles E. Grant
źródło
obsługa podwójnej precyzji jest częścią Shader Model 5, a także AMD / ATI.
Ben Voigt,
@Ben, dzięki za korektę. Usunąłem nieprawidłowe oświadczenie.
Charles E. Grant,
11

Procesory graficzne nie są procesorami ogólnymi, tak jak procesory. Specjalizują się w robieniu jednej bardzo konkretnej rzeczy - stosowaniu tego samego kodu do dużej ilości danych - i robią to bardzo, bardzo dobrze, znacznie lepiej niż procesor. Ale większość aplikacji nie polega na stosowaniu tego samego kodu do dużej ilości danych; chodzi o pętlę zdarzeń: oczekiwanie na dane wejściowe, czytanie danych wejściowych, działanie na nich, a następnie oczekiwanie na więcej danych wejściowych. To dość szeregowy proces, a procesory graficzne zasysają „serial”.

Kiedy masz dużą ilość danych, które musisz przetworzyć, a każdy element może być przetwarzany równolegle, niezależnie od innych, to idź dalej i wyślij go do GPU. Ale nie myśl o tym jako o „nowym paradygmacie”, w który wszystko trzeba wcisnąć.

To pytanie jest oznaczone jako „optymalizacja”, więc pamiętaj, aby traktować je jako jedno. Zastosuj optymalizację GPU, gdy testy i profilowanie ujawniają, że optymalizacja jest potrzebna, a charakter zadania jest taki, że można zastosować optymalizację GPU. W przeciwnym razie nie przejmuj się tym, ponieważ byłaby to przedwczesna lub niepoprawna optymalizacja, która powoduje więcej problemów niż naprawia.

Mason Wheeler
źródło
8

Prosta odpowiedź jest taka, że ​​GPU działa najlepiej, gdy trzeba wykonać dość małe, dość proste obliczenia dla każdego z bardzo dużej liczby elementów. Aby osiągnąć wiele w ten sposób, obliczenia dla każdego elementu muszą być niezależne od obliczeń dla innych elementów. Jeśli istnieje (normalnie) pewna zależność między jednym elementem a drugim, zazwyczaj musisz znaleźć sposób na jego zerwanie, zanim zaczniesz czerpać dużo korzyści z wykonywania tego kodu na GPU. Jeśli zależności nie można w ogóle przerwać lub wymaga ona zbyt dużo pracy, aby złamać, kod może zostać szybciej wykonany na procesorze.

Większość obecnych procesorów obsługuje także kilka rodzajów operacji, których obecne GPU po prostu nie próbują w ogóle obsługiwać (np. Ochrona pamięci dla wielozadaniowości).

Patrząc na to z nieco innej strony, procesory zostały (w dużej mierze) zaprojektowane tak, aby były dość wygodne dla programistów, a sprzęt, który ludzie zrobili, co w ich mocy (i cholernie dobrze!), Aby stworzyć sprzęt, który utrzymuje ten wygodny model dla programista, ale nadal działa tak szybko, jak to możliwe.

Procesory graficzne działają w zupełnie odwrotnym kierunku: są w dużej mierze wygodne dla projektantów sprzętu, a takie rzeczy jak OpenCL próbowały zapewnić możliwie rozsądny model programowania, biorąc pod uwagę ograniczenia sprzętowe.

Pisanie kodu do uruchomienia na GPU zwykle zajmuje więcej czasu i wysiłku (więc będzie kosztować więcej) niż robienie tego samego na CPU. Jako takie, ma to sens przede wszystkim wtedy, gdy:

  1. Problem jest tak równoległy, że można oczekiwać dużego zysku przy minimalnym wysiłku, lub
  2. Zwiększenie prędkości jest tak ważne, że uzasadnia wiele dodatkowej pracy.

Istnieją pewne oczywiste możliwości dla każdej z nich - ale ogromna liczba aplikacji najwyraźniej nawet nie jest zbliżona do żadnej z nich. Byłbym bardzo zaskoczony, gdy zobaczę (na przykład) aplikację CRUD działającą na GPU w najbliższym czasie (a jeśli tak się stanie, prawdopodobnie tak się stanie, ponieważ ktoś wyznaczył dokładnie ten cel, niekoniecznie coś zbliżającego się do optymalnego stosunek kosztów do korzyści).

Rzeczywistość jest taka, że ​​w przypadku wielu (mam ochotę powiedzieć „większość”) typowy procesor jest o wiele bardziej niż wystarczająco szybki, a wygoda programowania (prowadząca do łatwiejszego rozwoju nowych funkcji) jest znacznie ważniejsza niż szybkość wykonania.

Jerry Coffin
źródło
3

będziesz w stanie wykonać wiele obliczeń jednocześnie i naprawdę poprawić prędkość.

poprawić prędkość? Więc co? Przez ostatni rok pamiętam tylko raz lub dwa razy, kiedy było to potrzebne. Przez większość czasu proszono mnie o modyfikację lub naprawę logiki, dostosowanie do innego źródła danych, poprawę interakcji użytkownika itp. Jedyną szybkością, którą klienci byli zainteresowani w tych przypadkach, była szybkość wprowadzania zmian. „Wypuść nową funkcję za miesiąc, a jeszcze lepiej - za dwa tygodnie”.

Nie zrozum mnie źle - jako programista lubię wyciskać procesory dokładnie. Po prostu ta sztuka nie jest zwykle bardzo poszukiwana.

Czy nadal istnieją pewne przypadki, w których przetwarzanie szeregowe jest jeszcze lepsze, szybsze i / lub bardziej wydajne niż równoległe?

Powiedziałbym, że jest wiele przypadków. Przetwarzanie szeregowe jest prostsze niż równoległe, co czyni go bardziej wydajnym we wszystkich przypadkach, gdy prędkość nie jest krytycznym wymogiem. Szeregowe przetwarzanie pozwala na łatwiejszą implementację skomplikowanej logiki i interfejsu użytkownika, łatwiej jest określić i przetestować, utrzymać i zmienić.

Z reguły szeregowe przetwarzanie pozwala na wyraźniejsze wyrażenie intencji programisty i łatwiejszy odczyt kodu. Powiedziałbym, że oszczędza najbardziej cenne i rzadkie zasoby - mózg programisty.

komar
źródło
2

Procesory są jeszcze bardziej wszechstronne. Na przykład procesory graficzne są bardziej wydajne niż procesory w pojedynczej precyzji, ale nie w podwójnej precyzji. Istnieje znacznie więcej bibliotek dla procesorów niż dla GPU.

quant_dev
źródło
3
Czy możesz podać trochę więcej szczegółów? Dostarczyłeś trzy stwierdzenia bez informacji ani wyjaśnień co do ich prawdziwości.
Brak skutecznych obliczeń z podwójną precyzją jest powszechnie
znany
@ quant: Twoje informacje są co najmniej 2 lata nieaktualne: 544 GigaFLOPS jest znacznie szybszy niż jakikolwiek główny procesor.
Ben Voigt,
@ Ben Nie widzę, gdzie twój link wspomina o wydajności podwójnej precyzji.
quant_dev
@quant: awurl.com/Tt7LAX8lH
Ben Voigt
2

Prostą zasadą jest, że jeśli to, co robisz, można sformułować w kategoriach konstrukcji z algebry liniowej i jest krytyczne czasowo, zrób to na GPU, w przeciwnym razie użyj procesora.

Procesory graficzne nie są jak duża liczba procesorów, mają bardzo różne charakterystyki wydajności.

dan_waterworth
źródło
Jeśli jest to „czas krytyczny”, prawdopodobnie nie masz czasu na zmianę konfiguracji GPU dla shadera obliczeniowego i przesłanie danych. Największą korzyścią są duże problemy.
Ben Voigt,
@Ben, myślę, że mamy różne definicje „czasu krytycznego”, mam na myśli to, że obliczenia są na ścieżce krytycznej przez znaczną ilość czasu.
dan_waterworth
1

Jeśli potrzebujesz surowego zgniatania liczb, procesory graficzne są najlepszym rozwiązaniem. Jednak wszystkie te ALU oznaczają, że jest mniej tranzystorów przeznaczonych do obwodów sterowania przepływem (rozgałęzienia). Jeśli więc musisz napisać coś, co wymaga dużo złożonego przepływu sterowania, wielu warunków warunkowych itp., Procesor będzie szybszy.

Alex
źródło