Na podstawie mojego doświadczenia, podsumuję kluczowe różnice pod względem wydajności pomiędzy równoległymi programami w procesorach i procesorach graficznych. Zaufaj mi, porównanie można zmienić z pokolenia na pokolenie. Po prostu wskażę, co jest dobre i jest złe dla procesorów i procesorów graficznych. Oczywiście, jeśli wykonasz program skrajnie, tj. Mając tylko złe lub dobre strony, będzie on działał szybciej na jednej platformie. Ale ich połączenie wymaga bardzo skomplikowanego rozumowania.
poziom programu Host
Kluczową różnicą jest to koszt transferu pamięci. Urządzenia GPU wymagają pewnych transferów pamięci. Koszt ten nie jest banalny w niektórych przypadkach, na przykład, gdy trzeba często przenosić duże tablice. Z mojego doświadczenia wynika, że koszty te można zminimalizować, ale większość kodu hosta przesyła się do kodu urządzenia. Jedyne przypadki, w których możesz to zrobić, to kiedy musisz wchodzić w interakcję z systemem operacyjnym hosta w programie, na przykład wyprowadzać na monitor.
poziom programu Device
Teraz przychodzimy aby zobaczyć złożony obraz, który nie został jeszcze w pełni ujawnione. Mam na myśli to, że w procesorach graficznych nie ma wielu tajemniczych scen, które nie zostałyby ujawnione. Mimo to, mamy dużo wyróżniać procesor i GPU (kod jądra) pod względem wydajności.
Istnieje kilka czynników, które zauważyłem, że znacznie przyczyniają się do różnicy.
GPU, które składają się z wielu jednostek wykonawczych, są przeznaczone do obsługi programów masowo równoległych. Jeśli masz mało pracy, powiedz kilka zadań sekwencyjnych i umieść te zadania na GPU, tylko kilka z tych wielu jednostek wykonawczych jest zajętych, więc będzie wolniejsze niż procesor. Z drugiej strony procesory radzą sobie z krótkimi i sekwencyjnymi zadaniami. Powód jest prosty, procesory są znacznie bardziej skomplikowane i potrafią wykorzystać paralelizm na poziomie instrukcji, podczas gdy procesory graficzne wykorzystują równoległość poziomu wątku. Cóż, słyszałem, że NVIDIA GF104 potrafi robić Superskalar, ale nie miałem szansy z tym skorzystać. Warto zauważyć, że w procesorach graficznych obciążenie pracą jest podzielone na małe bloki (lub grupy robocze w OpenCL), a bloki są ułożone w porcje, z których każda jest wykonywana w jednym procesorze strumieniowym (używam terminologii od NVIDIA) . Ale w procesorach bloki te są wykonywane sekwencyjnie - nie mogę myśleć o niczym innym niż pojedynczej pętli.
W przypadku programów o małej liczbie bloków będzie to prawdopodobnie prawdopodobnie, aby działał szybciej na procesorach.
- instrukcje przepływ sterowania
Gałęzie są złe rzeczy do GPU, zawsze. Należy pamiętać, że procesory graficzne preferują równe rzeczy. Równe bloki, równe wątki w blokach i równe wątki wewnątrz osnowy. Ale co jest najważniejsze?
***Branch divergences.***
Programistów Cuda/OpenCL nienawidzi rozbieżności między gałęziami. Ponieważ wszystkie wątki są w jakiś sposób podzielone na zestawy 32 wątków, zwane osnowami i wszystkimi wątkami w ramach wykonywania zniekształceń w kroku blokady, dywergencja rozgałęzień spowoduje serializację wątków w osnowie. W ten sposób czas wykonania osnowy zostanie odpowiednio zwielokrotniony.
W przeciwieństwie do procesorów graficznych, każdy rdzeń procesora może podążać własną ścieżką. Co więcej, gałęzie mogą być wydajnie wykonywane, ponieważ procesory mają predykcje rozgałęzień.
W ten sposób programy, które mają więcej rozbieżności w osnowy, są prawdopodobnie, aby działać szybciej na procesorach.
to naprawdę jest wystarczająco skomplikowane, więc zróbmy to krótko.
Należy pamiętać, że dostęp do pamięci globalnej ma bardzo duże opóźnienie (400-800 cykli). Tak więc w starych generacjach procesorów graficznych decydujące znaczenie ma to, czy dostęp do pamięci jest połączony. Teraz twój GTX560 (Fermi) ma więcej 2 poziomów pamięci podręcznych. W wielu przypadkach koszt dostępu do pamięci globalnej może być zmniejszony. Jednak pamięci podręczne w procesorach i procesorach graficznych są różne, więc ich efekty są różne.
To, co mogę powiedzieć, to to, że naprawdę zależy to od wzorca dostępu do pamięci, schematu kodu jądra (jak dostęp do pamięci jest przeplatany za pomocą obliczeń, rodzajów operacji itp.), Aby stwierdzić, czy działa się szybciej na procesorach graficznych lub procesory.
Ale jakoś można się spodziewać ogromnej liczby braków pamięci podręcznej (w GPU) ma bardzo zły wpływ na procesory graficzne (jak źle? - to zależy od kodu).
Ponadto pamięć współdzielona jest ważną funkcją układów GPU. Dostęp do pamięci współdzielonej jest tak szybki, jak dostęp do pamięci podręcznej GPU L1. Więc jądra, które korzystają z pamięci współdzielonej, przyniosą wiele korzyści.
Niektóre inne czynniki nie zostały wymienione, ale te naprawdę mogą mieć duży wpływ na wydajność w wielu przypadkach, takich jak konflikty bankowych, wielkość transakcji zajętości pamięci, GPU ...
Proszę przeczytać [ten blog post] (http://blog.stackoverflow.com/2011/08/gorilla-vs-shark/), zanim zadasz więcej pytań na stackoverflow. – talonmies
@talonmies: Nie zgadzam się: to bardzo szczegółowe pytanie z bardzo konkretną odpowiedzią. Jedynym argumentem przeciwko temu jest to, że jest to * prawdopodobnie * duplikat jakiegoś innego pytania. –
możliwy duplikat [GPGPU kontra Multicore?] (Http://stackoverflow.com/questions/5919172/gpgpu-vs-multicore) –