NVIDIA CUDA (Compute Unified Device Architecture) to platforma obliczeniowa i model programowania opracowany przez firmę NVIDIA, umożliwiający wykorzystanie procesorów graficznych do ogólnych obliczeń równoległych. CUDA pozwala programistom na bezpośrednie programowanie GPU przy użyciu języków takich jak C, C++ czy Fortran, rozszerzonych o specjalne instrukcje umożliwiające wykorzystanie mocy obliczeniowej GPU. Technologia CUDA wprowadza model programowania oparty na hierarchii wątków, bloków i siatek, co umożliwia programistom na precyzyjny przydział zasobów i synchronizację danych w programach równoległych.

Podstawowe koncepcje technologii CUDA

Model programowania CUDA

Model programowania CUDA opiera się na koncepcji masowo równoległego wykonywania obliczeń poprzez podział pracy na hierarchicznie zorganizowane jednostki obliczeniowe: wątki (ang. threads), bloki wątków (ang. blocks) oraz siatki bloków (ang. grids). W tradycyjnym programowaniu CPU operacje są realizowane sekwencyjnie lub w bardziej ograniczonym zakresie równoległości (na kilku rdzeniach procesora). Technologia CUDA umożliwia jednoczesne wykonywanie tysięcy wątków na tysiącach rdzeni GPU, co wynika z architektury tych układów. Każdy wątek wykonuje tę samą funkcję (tzw. kernel), ale operuje na różnych fragmentach danych, realizując w ten sposób model obliczeń SIMD.

Technologia CUDA wykorzystuje także model SIMT (Single Instruction Multiple Threads), który oznacza, że grupy wątków wykonują te same instrukcje w tym samym czasie, ale mogą operować na różnych danych. Jeśli niektóre wątki w grupie wątków wykonują inne ścieżki kodu (np. instrukcje warunkowe), to może dojść do zjawiska rozgałęzienia (warp divergence), co może negatywnie wpłynąć na wydajność. Programista ma kontrolę nad sposobem alokacji wątków i bloków, co pozwala na optymalizację dostępu do hierarchii pamięci, minimalizację konfliktów pamięciowych oraz efektywne wykorzystanie dostępnych zasobów sprzętowych.

Grupy wątków

Wątki, bloki i siatki bloków to elementy hierarchicznej struktury obliczeniowej technologii NVIDIA CUDA. Takie podejście umożliwia sprawny podział obliczeń na mniejsze jednostki logiczne, co w konsekwencji umożliwia sprawny ich przydział do sprzętowych jednostek organizacyjnych w układzie GPU.

Każdy program zrealizowany w technologii CUDA definiuje funkcję jądra (kernel), którą uruchamia się równolegle, na wielu wątkach jednocześnie. Wątki są podstawową jednostką wykonawczą i grupowane są w bloki wątków (np. 32, 64, 128, 256), które z kolei są organizowane w siatki bloków. Ta hierarchia umożliwia skalowanie obliczeń w zależności od dostępnych zasobów sprzętowych.

Model pamięci programowalnej

Dostęp do różnych typów pamięci ma zróżnicowany czas opóźnienia, efektywne zarządzanie pamięcią może znacząco zwiększyć szybkość działania aplikacji. W technologii CUDA istnieje kilka poziomów pamięci, które różnią się dostępnością, pojemnością i czasem dostępu. Hierarchia ta obejmuje ****rejestry oraz pamięć ****współdzieloną, globalną, stałą, tekstur i powierzchni.

Ogólny schemat hierarchii pamięci CUDA

Rejestry:

Pamięć współdzielona: