Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Programowanie CUDA C++11; karty graficzne NVidia

PiotrLenarczyk 07 Nov 2017 10:56 4722 10
Computer Controls
  • #1
    PiotrLenarczyk
    Level 9  
    Jako, że już spędziłem ponad rok na programowaniu GPU napiszę poprawne (moim zdaniem) kroki do poznania technologii procesorów graficznych GPU. Dla niewtajemniczonych podsumuję jedynie, że jest to bardzo wydajny, energooszczędny i lepiej przystosowany do oprogramowania względem innych alternatywnych typów (FPGA), procesor (również koprocesor/procesor masowo równoległy). Efektywnie rozwiązuje większość problemów (problemy równoległe 2-3rzędy wielkości szybciej), również problemy sekwencyjne dla odpowiednio dużego zbioru danych(pojedynczy ze setek tysięcy wątek GPU vs pojedynczy wątek przypadający na pojedynczy rdzeń CPU dla tego samego problemu). Minimalne wymagania to znajomość języka C++ (polecam kursy online C: "https://www.tutorialspoint.com/cprogramming/index.htm"; C++: "https://www.tutorialspoint.com/cplusplus/") W kolejności:
    1)komputer, laptop, telefon, tablet, z kartą graficzną NVidia młodszą niż AGP GT6800 (zalecane min. PCIe1.0x16 GT9800 w cenie kilku piw; polecam nowe GT710 2GB - starczy na bardzo długo, cena ok. 150zł; sam piszę na GT1030 za 300zł); lub nowa płyta z procesorem (polecam Celeron G3900 - aż za szybki, a posiada bezpośrednie linie PCIe3.0x16, cena CPU z płytą 400zł); ram - wystarczy jedna kość używanej 4GB DDR3 1333MHz (90zł), polecam SSD 120GB Goodram (240zł) - przyśpiesza pracę niewymiernie - większość i tak niewielkich możliwości komputerów jest marnowana przez dyski talerzowe,
    2)system LINUX(polecam) Ubuntu desktop 64bit notatnik+terminal np. #sudo apt-get install kate konsole#(instrukcja instalacji CUDA na kilka sposobów: "https://github.com/PiotrLenarczykAnonim/CUDA_examples/blob/master/00_introduction/step-by-step_Introduction.pdf"); lub Windows (nie polecam - problem użycia czegokolwiek więcej niż pojedynczego programu napisanego w Microsoft VisualStudio Community- nota bene dobrze zintegrowanego z technologią CUDA). Środowisko CUDA Toolkit jest udostępniane bezpłatnie przez NVidię (wraz z profesjonalnymi bibliotekami, kompilatorem, profilerem, debugerem, itd.) "https://developer.nvidia.com/cuda-downloads",
    3) książka po polsku "CUDA w przykładach. Wprowadzenie do ogólnego programowania procesorów GPU" Autorzy: Jason Sanders, Edward Kandrot - wszystko krok po kroku (poza instalacją środowiska CUDA) i wytłumaczone bardzo prosto, "https://helion.pl/ksiazki/cuda-w-przykladach-wprowadzenie-do-ogolnego-programowania-procesorow-gpu-jason-sanders-edward-kandrot,cudawp.htm#format/d",
    4) napisanie kilkunastu własnych programów - najlepiej rozwiązujących rozwiązane poprawnie problemy na CPU,
    5) dopiero jak się rozumie i doskonale posługuje tematami zawartymi w książce p. Sandersa, to kolejno krok po kroku kurs na Youtube: "Udacity Intro to parallel programming" "https://www.youtube.com/watch?v=F620ommtjqk&list=PLAwxTw4SYaPnFKojVQrmyOGFCqHTxfdv2",
    6) po wykonaniu kilkunastu własnych programów, z użyciem technologii pokazanej na kursie YT, przeczytanie książki dla zaawansowanych: "Professional CUDA C Programming" Autor m.in.: John Cheng "https://krainaksiazek.pl/Professional-Cuda-C-Programming,9781118739327.html",
    7) książki polecam kupić (linki do sklepów przypadkowe), podeprzeć się wikipedią (dużo materiałów np. angielskojęzyczna "CUDA wiki", "NVidia gtx700 wiki"), unikać forów - sporo "speców" o wątpliwej wiedzy,
    8) tłumaczenie za rączkę uważam za zbędne - wszytko co szukasz w tym temacie znajdziesz w książce p. Sandersa,
    9) podpowiedź odnośnie przykładów NVidii pod Windowsem - wystarczy dodać while(1){}; przed linią return 0; aby obejrzeć efekt pracy danego programu,
    10) CUDA - to nazwa technologii (wewnętrzna struktura i budowa procesora graficznego - wstecz kompatybilna), języka programowania (okrojony C++11), środowiska programistycznego (min. klon Eclipse, NVCC, itd.), znaczenie słowa jest zależne od kontekstu.

    Efektem minimum kwartalnej pracy na pełnym etacie będzie możliwość podstawowego użycia technologii CUDA C na kartach korporacji NVidia i rozpoczęcia korzystania z urządzeń o rzeczywistych możliwościach obliczeniowych rzędu 500GFLOPS-6600GFLOPS za kilkaset zł. Parę lat temu coś takiego wymagało zespołu inżynierów, osobnego - specjalistycznego pomieszczenia i sporego rabatu w elektrowni, teraz każdy może oprogramować te procesory. Jak usłyszę, że brakuje możliwości obliczeniowych, albo nie stać - to zapraszam, proszę pisać w temacie, lub na email: "piotr.lenarczyk@wat.edu.pl":)

    Post Scriptum: sporo na temat C++; LINUX; CUDA-C++11 można znaleźć na moim wolnym repo (licencja w pełni otwarta, bez gwarancji i praw autorskich - używać do woli):
    " https://github.com/PiotrLenarczyk"
  • Computer Controls
  • #2
    JacekCz
    Level 39  
    Dzięki za obszerny i kompetentny materiał.

    Jaki masz pomysł co do dziedziny, zakresu problemów jaki "zwykły śmiertelnik" może obliczać w CUDA? Nawet hobbystycznie?

    Brałem się kiedyś wstępnie za to (dość przypadkowo wpadła mi ambitna nVidia, wspierana) , ale niczego z wektorowej numeryki (czy to się tak nazywa???) nie potrzebowałem, nawet w odcieniu hobbystycznym.

    Popieram myśl o papierowej książce, generalnie w programowaniu lubię "pierwsze czytanie" mieć w oparciu o książkę (chętnie polskie tłumaczenie - nawet do starszej wersji), zobaczyć to w panoramiczny sposób, potem poszerzać w oparciu o web (angielski).
  • Computer Controls
  • #3
    PiotrLenarczyk
    Level 9  
    Większość gotowych rozwiązań, bibliotek i dostępnych narzędzi jest w wersji "sekwencyjnej" - t.zn.wymyślona i optymalizowana pod pojedynczy rdzeń CPU. Jak się okazuje zwykłe duże pętle for (w tym zapętlone wielokrotnie) mogą być rozwiązywane równolegle w kilku cyklach GPU (gt1030 pracuje na 1.4GHz). Elektronik może najłatwiej zastosować bibliotekę cuFFT - nawet na najtańszych GPU efekty obliczania transformat są niezłe. To samo przetwarzanie strumieniowe obrazu, filmów, większość sortowań, przeszukiwania dużych zbiorów danych (kiedyś był pomysł na wydajny antywirus na GPU, ale został porzucony). Z doświadczenia wiem, że jeśli rozmiar np. wektora przekracza 8k zmiennych typu float, to już opłaca się obliczać na karcie graficznej - po prostu czas wykonania programu jest krótszy. Odradzam gotowe narzędzia typu akcelerowane oprogramowanie - efekty są słabe (kilka razy szybciej). Naprawdę wydajne (setki-kilkadziesiąt tysięcy razy szybciej) obliczenia uzyskuje się jeśli dane są przechowywane w pamięci globalnej GPU i tam przetwarzane. CPU służy jako sterownik dysku i sieci, RAM jako programowalna przestrzeń dyskowa i tyle.
  • #4
    JacekCz
    Level 39  
    PiotrLenarczyk wrote:
    Większość gotowych rozwiązań, bibliotek i dostępnych narzędzi jest w wersji "sekwencyjnej" - t.zn.wymyślona i optymalizowana pod pojedynczy rdzeń CPU. Jak się okazuje ....


    Co do "niesekwencyjnych" czy "mniej sekwencyjnych", to kibicuję od jakiegos czasu "klasycznym" procesorom wielordzeniowym, cache, wątkom itd... (tak, wiem, to nie identyczne zagadnienia jak GPU). Paradoksalnie najbardziej plastycznie to potrafią przedstawić "pozytywnie zarażeni" inżynierowie Java Virtual Machine, gdzie umiejętności programisty są raczej tradycyjne nazywane "wysokopoziomowe". Ale jedne ujęcia algorytmów mają naturalną podatność na zwielokrotnienie (z kolei mając dodatkowe koszty, lub nie), inne nie są podatne wcale.
  • #5
    PiotrLenarczyk
    Level 9  
    Też piszę programy wielordzeniowe. Mogę podpowiedzieć, wydajne rozwiązania (moim zdaniem):
    1) GNU Octave(prototypowanie) / C++11(produkt końcowy) program jednowątkowy napisany pod pojedynczy rdzeń procesora
    2) LINUX GNU Parallel
    3) flagi Makefile: "make -j`nproc`"
    4) unikanie Qt, od czasu zmiany polityki prawnej (oprogramowanie wytworzone na tym środowisku jest w połowie prezentowane za darmo tejże korporacji - wystarczy przeczytać licencję, zamiast klikać nieważne-next; zresztą licencje oprogramowania to jak kupno drogiego i nowego samochodu, który niewiadomo czy w ogóle działa i czy będzie nadal działał za kilka dni)
    Czas napisania programu jednowątkowego w C++ jest zwyczajnie krótszy, niż walka z dziedziczeniem w bibliotece <future>, poza tym i tak więcej rejestrów do architektury x86-64/AMD-64 programem wielowątkowym się nie doda. Intel HT - też nie dodaje, tylko trochę ulepsza wykorzystanie czasu oczekiwania na dane z (powolnego i wąskopasmowego nawet czterokanałowego)RAM.
    Programowanie CUDA C++11; karty graficzne NVidia
    5) używane serwery poprzednich generacji mają niezły (jak na klasyczne rozwiązania) współczynnik jakość/cena: np. Dell R610 16C; 48GB RAM 1.3kPLN; Dell R810 80C; 128GB RAM 9k PLN - źródło: popularny serwis do uzyskiwania danych osobowych Alledrogo:)
    Post Scriptum: wielowątkowość programu jest świetna w klikano-oglądanych aplikacjach, na których się nie znam.
    Post Post Scriptum: technologia RAM, jak i gigabit ethernet jest trochę przestarzała. Swego czasu się zastanawiałem, dlaczego nie powstało coś a'la architektura von Neumanna P4 z dyskoRAM'em na HBM, ale chyba tak to już jest z monopolistycznymi korporacjami, że po co wrzucać na rynek, jak rozwój można zablokować patentem (przy okazji rozwiązując problemem konkurencji) i sprzedać z zyskiem za kilka lat.
    JacekCz wrote:
    PiotrLenarczyk wrote:
    Większość gotowych rozwiązań, bibliotek i dostępnych narzędzi jest w wersji "sekwencyjnej" - t.zn.wymyślona i optymalizowana pod pojedynczy rdzeń CPU. Jak się okazuje ....


    Co do "niesekwencyjnych" czy "mniej sekwencyjnych", to kibicuję od jakiegos czasu "klasycznym" procesorom wielordzeniowym, cache, wątkom itd... (tak, wiem, to nie identyczne zagadnienia jak GPU). Paradoksalnie najbardziej plastycznie to potrafią przedstawić "pozytywnie zarażeni" inżynierowie Java Virtual Machine, gdzie umiejętności programisty są raczej tradycyjne nazywane "wysokopoziomowe". Ale jedne ujęcia algorytmów mają naturalną podatność na zwielokrotnienie (z kolei mając dodatkowe koszty, lub nie), inne nie są podatne wcale.
  • #6
    PiotrLenarczyk
    Level 9  
    Dorzucę jeszcze wspóczynniki jakości do ceny wybranych GPU:
    Programowanie CUDA C++11; karty graficzne NVidia
    oraz rzeczywiste przepływności ("przepustowość rzeczywista" - obiecać w warunkach laboratoryjnych można wszystko), uzyskane przy pomocy programu CUDA-Z (kiedyś pisałem swój benchmark na GPU, ale ten jest chyba dokładniejszy):
    Programowanie CUDA C++11; karty graficzne NVidia
    Wyniki dla dla serii 10 będą wyższe, dla wszystkich urządzeń o co najmniej architekturze sm 60 (ilość rejestrów FPR pojedynczego fizycznego rdzenia CUDA została podwojona w tychże urządzeniach drugiej generacji Maxwell).
    Podpowiem, że na moim Celeronie G3900 jest na dwukanałowym RAM'ie (DDR3 1333MHz CL9) o teoretycznej przepustowości 20GBps, a praktycznej przepływności (własny benchmark pod złożoność ówcześnie analizowanego algorytmu w C) 6.8GBps.
    Post Scriptum: różnice w czasach wykonywania mam zazwyczaj od 2000 razy do dwudziestukilku tysięcy razy szybciej na GPU względem CPU (wszystko napisane w CUDA C++11 i liczone w pamięci globalnej GPU). Podstawowym błędem jest przyśpieszanie pojedynczej funkcji - trzeba całość napisać od nowa (a dane przetwarzać na pamięci globalnej, bez zbędnych transferów do i z RAM). Rozważmy program składający się w 80% z pojedynczej funkcji możliwej do zrównoleglenia i 20% pozostałych operacji. Jeśli nawet zredukuje się czas wykonywania tej funkcji do 0s to całościowo przyśpieszenie wynosi zaledwie 5 razy - bez zrozumienia tego tematu nie da się czegokolwiek rozsądnie przyśpieszyć.
    Post Post Scriptum: nie pracuję w NVidii - temat hobbystyczny. Moim zdaniem prościej jest umieć chociaż trochę jeden język programowania (C++), niż zapoznać się z kilkoma i z tego powodu wybrałem NVidię z CUDA-C++11, zamiast uczyć się OpenCL na AMD HD5770/R9Nano/RX64 Vega.
    Dodano po 37 [minuty]:
    Zwolennicy FPGA powinni rozważyć:
    -float nie istnieje w wydajnej formie, to samo się dotyczy emulowanych rdzeni np. ARM i innych,
    -obliczenia całkowitoliczbowe są wydajniejsze, ale nie spotkałem jeszcze rozbudowanej biblioteki obliczeń fixed point na FPGA (na DSP udostępnia za darmo Texas Instruments),
    -problemy przepływów danych, 
    -brak znanych mi narzędzi automatycznych do poszukiwania hazardów,
    -często kończy się na średniej wydajności kosztem dużej ilości pracy,
    -interlink - czy jak tam się nazywa matryca połączeń Logic Cells (2 do 8TBps) wypada o wątpliwej wydajności wzgledem łatwości oprogramowania rejestrów GPU (GTX1080ti za 3.3kPLN to 3.5k rdzeni i 7MB FPR ze sporym zakresem instrukcji jednocyklowych). Rejestry zgaduję, że mają przepływności ok. 1TBps,
    -FPGA nie posiada dużej pamięci masowej o dużej przepustowości za rozsądna cenę,
    -nie jestem przeciwnikiem FPGA-po prostu zrobiłem research przed straceniem ileś tam czasu,
    -FPGA jako przetwornik dla GPU jest gdzieniedzie (SETI@HOME) wydajnie używane, to samo dotyczy urządzeń sieciowych,
    -wypadają najlepiej jeśli chodzi o pobieraną moc - więc większość mobilnych zastosowań powinno zawierać (a o dziwo typowo nie zawiera) FPGA,
    -w Polsce oba tematy to egzotyka, prawie nikt się na obu zna.
    O programowaniu CPU szkoda gadać - moim zdaniem popularność wynika z siły pierwszego wrażenia dla początkującego programisty, przyzwyczajeń, błędnie utrwalanych stareotypów ("droga" pamięć podręczna:D) i długofalowo nie stanowi przyszłości moim zdaniem (kto jeszcze pamięta, gdzie znaleźli zatrudnienie inżynierowie Qimondy).
  • #7
    kaamil1984
    Level 12  
    JacekCz wrote:
    Jaki masz pomysł co do dziedziny, zakresu problemów jaki "zwykły śmiertelnik" może obliczać w CUDA? Nawet hobbystycznie?


    Ja mam.

    Można zamontować w kurniku kamerę i za pomocą Computer Vision liczyć kurczaki. Kiedy wszystkie znajdą się w środku - można zamknąć kurnik i wysłać powiadomienie na smartfona, że kurczaki poszły spać.

    Wymyślać dalej? :)
  • #8
    PiotrLenarczyk
    Level 9  
    W związku z medianowym, błędnym podejściem do rozwiązywania problemów numerycznych, podpowiem swój sposób na dowolny algorytm:
    1) dokładne zapoznanie się z problemem:
    -przegląd literatury zaczynając od naukowych baz danych ( Elsevier, Springer, sporo jest na konferencyjnych materiałach na IEEE ) - dostęp za darmo dla studentów, lub dość tanio komercyjnie, potem internet, trochę fora ( które zresztą odradzam ), można zapłacić za konsultacje z osobą niezależną w danej dziedzinie ( obowiązuje niestety: "ALBO SPECJALISTA, ALBO NIEZALEŻNY!" ),
    -sprawdzenie technologii alternatywnych ( zamiast prowadzić rozważania "-co jest lepsze: auta z Niemiec, czy niemieckie samochody?" ),
    2) napisanie działającego prototypu ( najlepszy program to ten co działa ), używam GNU Octave zwielokrotnione o please-cite-GNU-Parallel,
    3) SZEROKO ZAKROJONE TESTY, SKUTKUJĄCE ULEPSZANIEM PROTOTYPU. Ten etap zajmuje 70-95% czasu, a jest głupio pomijany ( podejście "byle działało i więcej w umowie przetargowej nie było" ). Przeprowadzenie testów efektywności - krzywe operacyjne ROC dla algorytmów decyzyjnych ( minimum to progowanie detektora na błędy false-positive ), współczynniki urealniające sens działań ( efektywność pozyskiwania, zysk przetwarzania, rzeczywisty rozwój dziedziny do wydanych środków, itd. ),
    4) jeśli prototyp jest oparty o sprzęt, to minimalnie należy posiadać DWIE takowe platformy. Warto w prototypach użyć lepszej jakości sprzętu, a w docelowym produkcie schodzić z kosztami na samym końcu, najlepiej już w drugiej generacji sprzętu - po wyeliminowaniu błędów zerowej generacji,
    5) przechowywanie dwóch ostatnio działających wersji programu,
    6) napisanie wydajnego, zoptymalizowanego pod daną architekturę ( inaczej się pisze np. program na telefonowe GPU Mali w OpenCL, niż zwykły desktopowy ), tutaj unikam języków wysokiego poziomu ( R, Octave, a już na pewno Matlab ), najlepiej wypada C++11 ( język średniego poziomu w którym jest napisana znakomita większość pozostałych "https://en.wikipedia.org/wiki/List_of_C-family_programming_languages", w tym Java )
    7) jakiś wymierny efekt, kończący prace - w najgorszym przypadku chociaż publikacją ( najlepiej się publikuje w lokalnych wydawnictwach uczelnianych, najłatwiej się awansuje po płatnych, znanych typu Elsevier, Springer - trzeba tylko uważać, żeby nie zachorować na "punktozę":D ), może być wolne repozytorium, materiały szkoleniowe, zorganizowanie kursu, artykuł w gazecie (Elektronika, Elektronika Praktyczna, Wiedza i Życie, itd.), itp.,
    8) moim zdaniem najwydajniej rozwijają się projekty komercyjne, otwarte ( nie mylić ze startapami ).
  • #10
    PiotrLenarczyk
    Level 9  
    Trochę odgrzewam temat - otóż dochodzę do wniosku, że najlepsze wyniki ( kilka tysięcy do kilkudziesięciu tysięcy razy szybciej; medianowo uzyskuję czasy egzekucji programu z minut CPU do milisekund GPU ) otrzymuje się dla podejścia opisanego pod koniec książki dla początkujących "CUDA w przykładach" p. Sandersa ( bardzo przystępnie napisanej, nawet dla niezaawansowanego programisty ). Biblioteki warto używać aby nie przepisywać już napisanych algorytmów ( najbardziej popularne: redukcja, skan, sortowanie, przeszukiwanie ), poza tym typy danych i składnia jest w górę kompatybilna ( na przykład biblioteki: Thrust, cuSolver, cuFFT ). Podsumowując całość powinna być napisana głównie w CUDA C++11 ( używanie pinned memory, streams, sprawdzenie błędów malloc, itd. ).
  • #11
    PiotrLenarczyk
    Level 9  
    Zmieniłem nazwę (adres) repozytorium na bardziej poważną:
    https://github.com/PiotrLenarczyk
    Powodzenia w akceleracji i proszę pamiętać, że pierwsze efekty min. po miesiącu ( jak w bieganiu :). GT1030 za 350-400zł to 1TFLOP możliwości obliczeniowych - umiejętnie użyte odpowiada wydajności flagowego, klasycznego serwera firmy Dell tj. R930 za ćwierć miliona PLN.