Techniki zmniejszające opóźnienie transferu danych procesora do GPU

Szukałem sposobów na zmniejszenie opóźnień spowodowanych przesyłaniem danych tam iz powrotem z procesora i GPU. Kiedy po raz pierwszy zaczął używać CUDA zauważyłem, że transfer danych między procesorem i GPU nie trwało kilka sekund, ale tak naprawdę nie obchodzi mnie, bo to nie jest tak naprawdę problemem dla małych programów jestem pisanie. W rzeczywistości opóźnienie prawdopodobnie nie stanowi większego problemu dla większości programów wykorzystujących GPU, w tym gry wideo, ponieważ są nadal dużo szybciej niż gdyby działały na procesorze.

Jednak jestem trochę entuzjastą HPC i zainteresowałem się kierunkiem moich studiów, kiedy zobaczyłem ogromną rozbieżność między teoretycznymi klapami szczytowymi Tianhe-I a rzeczywistą wydajnością mierzoną przez LINPACK. To wzbudziło moje obawy dotyczące tego, czy obramuję właściwą ścieżkę kariery.

Użycie pamięci przypinanej (page-locked) poprzez użycie funkcji cudaHostAlloc() jest jedną z metod redukcji latencja (dość skuteczna), ale czy są jakieś inne techniki, których nie znam? A żeby było jasne, mówię o optymalizacji kodu, a nie samego sprzętu (to zadania Nvidii i AMD).

Jako pytanie poboczne, wiem, że Dell i HP sprzedają serwery Tesla. Jestem ciekaw, jak dobrze GPU wykorzystuje aplikację bazodanową, w której potrzebny byłby stały odczyt z dysku twardego (HDD lub SSD), operacja może wykonać tylko procesor,

Author: Elad Maimoni, 2011-06-28

3 answers

Istnieje kilka sposobów, aby rozwiązać problem komunikacji CPU-GPU-mam nadzieję, że to masz na myśli przez opóźnienie, a nie opóźnienie samego transferu. Zauważ, że celowo użyłem terminu address zamiast reduce, ponieważ niekoniecznie musisz zmniejszać opóźnienie, jeśli możesz go ukryć. Zauważ również, że jestem znacznie bardziej zaznajomiony z CUDA, więc poniżej odnoszą się tylko do CUDA, ale niektóre funkcje są również dostępne w OpenCL.

Jak wspomniałeś pamięć zablokowana na stronie ma na celu zwiększenie. Dodatkowo, można mapować pamięć hosta z blokadą strony do GPU, mechanizmu, który umożliwia bezpośredni dostęp do danych przydzielonych z jądra GPU bez konieczności dodatkowego transferu danych. Mechanizm ten nazywany jest transferem zero-copy i jest przydatny, gdy dane są odczytywane/zapisywane tylko raz, wraz ze znaczną ilością obliczeń i dla GPU bez oddzielnej pamięci (mobile). Jednakże, jeśli jądro uzyskujące dostęp do zerowo skopiowanych danych nie jest silnie obliczanie związane i dlatego opóźnienie dostępu do danych nie może być ukryte, strona zablokowana, ale nie zmapowana pamięć będzie bardziej wydajna. Dodatkowo, jeśli dane nie mieszczą się w pamięci GPU, Kopia zerowa nadal będzie działać.
Należy pamiętać, że nadmierna ilość pamięci zablokowanej stroną może spowodować poważne spowolnienie po stronie procesora.

Podchodzenie do problemu pod innym kątem, jak wspomniał tkerwin, asynchroniczny transfer (wrt wątek CPU rozmawiający z GPU) jest kluczem do ukrycia CPU-GPU opóźnienie transferu poprzez nakładanie się obliczeń na procesor z transferem. Można to osiągnąć za pomocą cudaMemcpyAsync(), jak również za pomocą kopii zerowej z asynchronicznym wykonaniem jądra.
Można to zrobić jeszcze dalej, używając wielu strumieni do nakładania się transferu z wykonaniem jądra. Należy pamiętać, że planowanie strumienia może wymagać szczególnej uwagi dla dobrego nakładania się; karty Tesla i Quadro mają silnik dual-DMA, który umożliwia jednoczesne przesyłanie danych do iz GPU. Dodatkowo z CUDA 4.0 stał się łatwiejsze w użyciu GPU z wielu wątków procesora, więc w wielowątkowym kodzie procesora każdy wątek może wysyłać własne dane do GPU i łatwiej uruchamiać jądra.

Wreszcie, GMAC implementuje asymetryczny model pamięci współdzielonej dla CUDA. Jedną z jego bardzo ciekawych cech są modele coherencji, które zapewnia, w szczególności leniwa-i rolling update umożliwiająca transfer Tylko danych modyfikowanych na procesorze w sposób zablokowany.
Więcej szczegółów w poniższym artykule: [[25]} Gelado et al. - Asymetryczna Rozproszona Pamięć Dzielona Model dla heterogenicznych układów równoległych .

 17
Author: pszilard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-29 01:20:55

Możesz użyć cudaMemcpyAsync() do nakładania pracy na procesor z transferem pamięci. Nie zmniejszy to opóźnienia transferu danych, ale może poprawić ogólną wydajność algorytmu. Istnieje kilka informacji na ten temat w CUDA C Best Practices guide.

 4
Author: tkerwin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-28 03:07:46

Jeśli opóźnienie jest problemem, warto przyjrzeć się kompromisom, jakie można osiągnąć z architekturą AMD fusion. Opóźnienie jest drastycznie zminimalizowane i w niektórych przypadkach może być szybsze niż transfer PROCESORA z pamięci RAM. Jednak osiągniesz hit dzięki odchudzonemu, nie-dyskretnemu procesorowi graficznemu.

 1
Author: homemade-jam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-17 21:46:46