Що таке програмування GPU?
У світі високопродуктивних обчислень GPU (графічні процесори) є всюди, і науковці, що працюють у певних галузях, стикаються з дедалі складнішим завданням. А саме: їм потрібно доопрацьовувати свої комп'ютерні програми, щоб максимально використовувати ці сучасні GPU-системи. Це завдання важливе для того, щоб розкрити всю потужність цих високотехнологічних архітектур GPU.
У цій статті ми дамо базове розуміння програмування GPU тим, хто шукає відповідь на запитання «Що таке програмування GPU?». Крім того, ви розглянете різні підходи та фреймворки для GPU, а також найпопулярнішу платформу програмування GPU на Python, CUDA, і її значення для написання коду для GPU.
Що таке GPU?
Графічний процесор (GPU) - це електронна схема, яка прискорює створення зображень для виведення на екран завдяки швидкій роботі з пам'яттю та одночасній обробці даних. Сьогодні такі GPU є повсюди: вони є в різних обчислювальних пристроях, як-от персональні комп'ютери, ігрові консолі, професійні робочі станції і навіть смартфони.
З часом GPU перевершили CPU за продуктивністю: вони мають більше транзисторів і чудово справляються з паралельними обчисленнями. Перетворившись на складні пристрої з власною пам'яттю, шинами та процесорами, GPU можна розглядати як додатковий мозок або процесор комп'ютерної системи.
Що таке програмування GPU?
Програмування GPU використовує GPU-прискорювачі для одночасного виконання обчислювальних операцій надзвичайно загального призначення. У минулому GPU використовували переважно для комп'ютерної графіки, але тепер їх застосовують і для найрізноманітніших обчислювальних завдань загального призначення. Окрім створення графіки, GPU тепер широко використовують для наукового моделювання, машинного навчання та інших робіт, які можна виконати швидше, обробляючи багато завдань одночасно.
У чому різниця між GPU та CPU?
Основна відмінність між обчисленнями на GPU та CPU полягає в їхніх архітектурних особливостях. Завдяки високому рівню паралелізму GPU ефективніший за CPU в обробці даних, які можна розділити та обробляти кількома способами. GPU спеціально оптимізовані для інтенсивних обчислень, як-от матрична арифметика та арифметика з рухомою комою.
Різниця в обчислювальній потужності між CPU та GPU пояснюється тим, що GPU розроблені для виконання високопаралельних і обчислювально інтенсивних завдань, а саме цього й вимагає рендеринг графіки.
В архітектурі GPU пріоритет надається обробці даних, а не кешуванню даних і керуванню потоком виконання. Під час паралельного розв'язання задачі виникають дві помітні переваги: по-перше, для кожного елемента розв'язується одна й та сама задача, що зменшує потребу в складному керуванні потоком виконання; по-друге, великий набір даних і висока арифметична інтенсивність зменшують потребу в пам'яті з низькою затримкою.
Які підходи або API для програмування GPU використовуються?
До використання GPU для обчислень можна підходити по-різному. У найпростіших випадках, коли код уже написано, може бути достатньо налаштувати параметри та початкові конфігурації. Інший варіант - використати бібліотеки для найбільш ресурсомістких частин коду. Однак у складніших сценаріях може знадобитися певне програмування.
Існують різні програмні середовища та API для програмування GPU. Їх поділяють на моделі на основі директив, непереносні моделі на основі ядер і переносні моделі на основі ядер, а також на високорівневі фреймворки та бібліотеки.
Стандартні C++/Fortran
Програми стандартними мовами C++ і Fortran можуть використовувати GPU NVIDIA без зовнішніх бібліотек. Компілятори NVIDIA SDK оптимізують код для виконання на GPU, як показано в наведених рекомендаціях.
Програмування на основі директив
Підходи на основі директив передбачають анотування наявного послідовного коду, щоб позначити цикли та ділянки для виконання на GPU. Цей метод, прикладами якого є OpenACC і OpenMP, орієнтований на продуктивність розробки та простоту використання, але може дещо поступатися швидкодією.
OpenACC: консорціум, створений у 2010 році. OpenACC має на меті надати стандартну, переносну та масштабовану модель програмування для прискорювачів, зокрема GPU. Спочатку він підтримував лише GPU NVIDIA, але розширює підтримку на інші пристрої та архітектури.
OpenMP: спочатку це був API для паралельного програмування зі спільною пам'яттю для багатоядерних CPU, а тепер OpenMP підтримує перенесення обчислень на GPU і орієнтований на різні типи GPU.
Непереносні моделі на основі ядер (нативні моделі програмування)
Пряме програмування GPU дає розробникам більше контролю завдяки низькорівневому коду, що взаємодіє безпосередньо з GPU. Приклади: CUDA (NVIDIA) і HIP (AMD), причому HIP розроблено для сумісності між GPU NVIDIA та AMD.
Переносні моделі на основі ядер (кросплатформні екосистеми переносності)
Кросплатформні екосистеми переносності, як-от Alpaka, Kokkos, OpenCL, RAJA і SYCL, пропонують абстракції вищого рівня для зручного та переносного програмування GPU. Їхня мета - переносність продуктивності з єдиним вихідним кодом застосунку.
Kokkos: розроблена в Sandia National Laboratories, Kokkos - це екосистема на основі C++, що підтримує ефективні та масштабовані паралельні застосунки на CPU, GPU і FPGA.
OpenCL: відкритий стандартний API для паралельних обчислень загального призначення на різному обладнанні. OpenCL надає низькорівневий програмний інтерфейс для програмування GPU. Він підтримує CPU, GPU і FPGA від багатьох виробників.
SYCL: безкоштовна (без ліцензійних відрахувань) модель програмування на C++ з відкритим стандартом. SYCL надає високорівневу модель програмування з єдиним вихідним кодом для гетерогенних систем, зокрема GPU. Її можна реалізувати поверх OpenCL, CUDA або HIP.
Підтримка у високорівневих мовах
Python підтримує програмування GPU за допомогою кількох бібліотек, кожна з яких має своє призначення:
CuPy
- Бібліотека масивів даних на основі GPU.
- Безпроблемна інтеграція з NumPy/SciPy.
- Простий перехід до обчислень на GPU: достатньо замінити 'numpy' і 'scipy' на 'cupy' і 'cupyx.scipy' у коді Python.
cuDF (RAPIDS)
- Частина RAPIDS, що реалізує функціональність CUDA з прив'язками до Python.
- Призначена для роботи з датафреймами на GPU.
- Пропонує API, подібний до pandas, що дає змогу користувачам, знайомим із Pandas, прискорити роботу без глибоких знань CUDA.
PyCUDA
- Середовище програмування на Python для CUDA.
- Надає доступ до CUDA API від NVIDIA з Python.
- Працює лише з GPU NVIDIA і потребує досвіду програмування на CUDA.
Numba
- Дає змогу виконувати JIT-компіляцію (Just-In-Time) коду Python для виконання на GPU.
- Підтримує GPU NVIDIA, а в майбутньому очікується підтримка GPU AMD.
Ці бібліотеки надають різноманітні варіанти програмування GPU на Python з урахуванням різних уподобань і потреб користувачів. Чи то перехід із NumPy/SciPy за допомогою CuPy, чи то використання API cuDF, подібного до pandas, Python забезпечує гнучкість для ефективних обчислень із прискоренням на GPU.
Що таке CUDA?
CUDA - це платформа паралельних обчислень і API, створені NVIDIA, з яких почалася ера масових фреймворків для програмування GPU. Ця технологія дає змогу розробникам писати код, схожий на C++, який виконується на GPU.
CUDA не лише надає безліч бібліотек та інструментів для низькорівневого програмування GPU, а й значно підвищує ефективність обчислювально вимогливих застосунків. Слід зазначити, що CUDA працює лише з обладнанням NVIDIA, попри таку потужну екосистему.
Як встановити CUDA на Ubuntu 20.04 для програмування GPU
Ви можете встановити CUDA на Ubuntu 20.04, виконавши наведені нижче покрокові інструкції:
Крок 1: спочатку завантажте файл конфігурації пріоритету CUDA (cuda-ubuntu2004.pin), потрібний для налаштування репозиторіїв CUDA на Ubuntu 20.04, за допомогою команди ‘wget’ або ‘curl’.
$ wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pinКрок 2: перемістіть завантажений файл конфігурації пріоритету до вказаного каталогу, встановивши для нього пріоритет 600.
$ sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600Крок 3: завантажте пакет репозиторію CUDA:
wget https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda-repo-ubuntu2004-11-4-local_11.4.2-470.57.02-1_amd64.debКрок 4: встановіть завантажений пакет репозиторію CUDA за допомогою менеджера пакетів dpkg.
$ sudo dpkg -i cuda-repo-ubuntu2004-11-4-local_11.4.2-470.57.02-1_amd64.debКрок 5: додайте публічний ключ, потрібний для автентифікації репозиторію CUDA.
$ sudo apt-key add /var/cuda-repo-ubuntu2004-11-4-local/7fa2af80.pubКрок 6: оновіть списки пакетів:
$ sudo apt-get updateОновіть локальні списки пакетів інформацією з щойно доданого репозиторію CUDA.
Крок 7: тепер встановіть CUDA Toolkit на свою машину з Ubuntu 20.04 за допомогою такої команди:
$ sudo apt-get -y install cudaВиконавши наведені вище кроки, ви зможете встановити CUDA на машину з GPU, що підтримує CUDA, під керуванням Ubuntu 20.04. Тепер ви можете запускати код для GPU і використовувати платформу CUDA на своїй Linux-машині.
Висновок
Вибір середовища програмування GPU залежить від таких чинників, як цільові апаратні платформи, характер обчислень і досвід розробника. Сумісність із конкретними GPU, відповідність вимогам проєкту та вподобання розробника щодо високорівневої простоти чи низькорівневого контролю - ключові міркування для оптимального вибору.