Programowanie na platformie CUDA
Dziesięć lat temu kolejne generacje procesorów charakteryzowały się wykładniczo rosnącą częstotliwością taktowania. Teraz ta sytuacja uległa zmianie. Obecnie to liczba rdzeni w jednym procesorze zaczyna rosnąć wykładniczo. W użytku są już procesory firmy Intel dla zwyczajnych PC-tów mające 8 rdzeni, a co jakiś czas pojawiają się informacje o tym, że niedługo zostanie wyprodukowany procesor o 50 rdzeniach...
Niestety, pisanie programu, który wykorzystuje w pełni moc  
 rdzeni,
nie jest dla programisty łatwym zadaniem. Jest to spowodowane dość
uciążliwymi metodami synchronizacji wielu wątków i używanym
modelem pamięci, który jest bardziej przystosowany do programowania
jednowątkowego.
Okazuje się, że w większości współczesnych komputerów znajduje się drugi układ scalony, który od początku był projektowany do obliczeń równoległych. Chodzi o kartę graficzną. Zwyczajowo karta graficzna ma za zadanie obliczyć wartości koloru pojedynczych pikseli na ekranie. Widać, że wyniki poszczególnych obliczeń są niezależne. W tym artykule chciałbym przybliżyć platformę CUDA, która służy do programowania na kartach graficznych firmy NVIDIA. O tym, że warto zastanowić się nad programowaniem na karcie graficznej, może świadczyć następujące porównanie:
- jeden z najlepszych obecnie procesorów Intela – Core i7 980X – kosztuje ok. 1000 dolarów i osiąga moc obliczeniową ok. 100 Gflopsów;
 - jedna z najlepszych kart graficznych NVIDIA – GeForce GTX 580 – kosztuje ok. 500 dolarów i oferuje moc obliczeniową ok. 1500 Gflopsów.
 
Struktura karty graficznej
Karta graficzna składa się (w uproszczeniu) z multiprocesorów, przy czym jeden multiprocesor składa się z 8 lub 16 pojedynczych procesorów i jednej niewielkiej współdzielonej pamięci na cały multiprocesor (pamięć multiprocesora jest szybka, umożliwia jednoczesny odczyt/zapis), oraz jednej dużej pamięci, która jest wspólna dla wszystkich multiprocesorów. Pamięć ta jest o rząd wielkości wolniejsza od pamięci multiprocesora, umożliwia także jednoczesny odczyt/zapis.
    
    Rys. 1 Struktura karty graficznej (część zacieniona) i przepływ danych w pamięci komputera podczas obliczeń.
Standardowo program używający do obliczeń karty graficznej będzie działał według następującego schematu: skopiowanie danych z pamięci komputera do pamięci głównej karty graficznej i dalej do pamięci multiprocesora; wykonanie obliczenia na multiprocesorach; skopiowanie częściowych wyników z pamięci multiprocesora do pamięci głównej karty graficznej i skopiowanie końcowego wyniku do pamięci komputera.
Struktura obliczeń
    
    Rys. 2 Struktura obliczeń.
A teraz ciekawe pytanie: w jaki sposób programista rozdziela zadania między
multiprocesory i procesory? Przypuśćmy, że chcemy wykonać jakieś
duże obliczenie  
   Programista dzieli je na zbiór mniejszych obliczeń:
 
   Pojedynczy element obliczenia  
 to blok,
który jest z kolei złożony z pojedynczych wątków:
Specyfikacja techniczna platformy CUDA daje następujące gwarancje: każdy blok będzie wykonywany w obrębie jednego multiprocesora; nic nie wiadomo o tym, w jakiej kolejności wykonają się bloki; jeden wątek wykona się na jednym procesorze; w obrębie jednego multiprocesora wykonuje się w danym momencie co najwyżej jeden blok.
Zadaniem programisty jest napisanie kodu pojedynczego wątku. Każdy wątek wykonuje dokładnie ten sam kod, przy czym wątek może sprawdzić, w którym bloku się znajduje, a także jaki ma numer wewnątrz tego bloku. Obliczenie wykonywane przez wątek zależy od tak zdefiniowanych współrzędnych tego wątku.
Należy jeszcze podkreślić, że programista nie specyfikuje dokładnie, na którym procesorze wykona się dany wątek. Zadaniem programisty jest zdefiniować strukturę obliczeń, a przydziałem wątków do procesorów zajmuje się CUDA.
Praktyczny przykład – mnożenie macierzy
Chcemy pomnożyć dwie macierze  
  i  
  obie wymiaru
 
 Przez  
  oznaczmy macierz wynikową. Obliczenie macierzy
 
 wprost z definicji wymaga wykonania  
  operacji. Używając
platformy CUDA, można zaproponować lepsze rozwiązanie, w którym
wszystkie macierze dzielimy na podmacierze rozmiaru  
 (oznaczamy
je przez  
 ). Dla uproszczenia analizy założymy, że rozmiar
macierzy  
 jest wielokrotnością rozmiaru podmacierzy  
 Jeden
blok obliczenia będzie miał za zadanie obliczyć jedną z podmacierzy
 
 Zauważmy, że  
  W jednej iteracji
będziemy chcieli obliczyć jeden składnik postaci  
  Można to
zrobić następująco. 
- pobieramy         do         pamięci         multiprocesora         macierze
         
 – tę pracę wykonuje pierwszy wątek z każdego
        bloku;
            - równolegle
        obliczamy  
  każdej komórce macierzy wynikowej
        przyporządkowujemy jeden wątek dpowiedzialny za obliczenie tej
        wartości;
                                                                     
                                                                     
            - dodajemy do wyniku obliczoną wartość  
  
Po wykonaniu obliczeń dla wszystkich  
 mamy obliczoną podmacierz
 
 którą możemy zapisać do pamięci głównej karty.
    
    Rys. 3 Schemat mnożenia macierzy. Tutaj  
 oraz  
Spróbujmy oszacować złożoność tego rozwiązania. W tym celu przez
 
 oznaczmy liczbę procesorów wewnątrz jednego multiprocesora,
a przez  
  – liczbę multiprocesorów.
Przyjrzyjmy się czasowi wykonywania pojedynczego bloku. Przy obliczaniu iloczynu
 
 najpierw pobieramy dwie macierze rozmiaru  
  do
pamięci multiprocesora, co zajmuje czas  
           a następnie wykonujemy
 
 mnożeń, ale to zrównolegla się między  
 procesorów, koszt
tego wynosi więc  
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 Taki ciąg operacji należy wykonać
dla  
 Zatem jeden blok wykonuje się w czasie
 
Mamy  
 bloków, ich wykonanie zrównoleglamy między
 
 multiprocesorów, zatem łączny czas to  
 razy
czas wykonania pojedynczego bloku. Daje to złożoność czasową
 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   Przyjmując, że  
 co jest możliwe,
gdyż to programista dobiera wartość  
 daje to złożoność
 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   czyli   
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 W ten sposób klasyczną
złożoność  
      podzieliliśmy przez  
  czyli liczbę
procesorów. We wspomnianej wcześniej karcie GeForce GTX 580
mamy  
   
  czyli programista ma do dyspozycji
 
 procesorów. To daje duże możliwości zrównoleglania.
Czy przyszłość programowania leży w równoległości?
Jest cała lista problemów związanych z programowaniem równoległym, jak np.: mała liczba doświadczonych programistów; wyższy niż w przypadku programowania jednowątkowego poziom skomplikowania; część algorytmów ciężko się zrównolegla (np. nie jest znany dobry równoległy algorytm sprawdzania, czy w danym grafie dwudzielnym jest doskonałe skojarzenie); błędy typu race condition, gdy więcej niż jeden wątek jednocześnie zapisuje w danym miejscu w pamięci.
Z drugiej strony programiści chcieliby, aby ich programy działały szybko. Podnoszenie wydajności pojedynczego rdzenia nie odbywa się w takim tempie jak kiedyś, można więc przypuszczać, że do dalszego poprawiania wydajności oprogramowania potrzebne jest odrzucenie modelu programowania z jednym procesorem i myślenie w sposób równoległy. NVIDIA CUDA jest jednym z ciekawszych modeli oferujących możliwość programowania współbieżnego. Wprowadza to za cenę jednej zasadniczej nowości: programiści muszą nauczyć się dzielić obliczenia tworzonego oprogramowania na możliwie niezależne kawałki. Nie jest to takie łatwe, bo całkowicie zmienia sposób myślenia o programowaniu.
 oraz