Траектория «Параллельные вычисления» · линия C · конспект 1 из 8

Рабочее место: установка CUDA и компиляция .cu-файлов

О чём эта тема
Подготовка рабочего места для программирования видеокарты: проверка железа, установка CUDA Toolkit, устройство .cu-файла и компилятора nvcc, первая скомпилированная и запущенная программа — и запасной аэродром в облаке для тех, у кого нет карты NVIDIA.
Аннотация
Сначала выясняем, подходит ли компьютер: как прочитать вывод nvidia-smi и что такое вычислительная способность (compute capability). Затем ставим инструменты: на Windows — Visual Studio и CUDA Toolkit (и почему именно в таком порядке), на Linux — пакет от NVIDIA. Центральная часть — что лежит в файле с расширением .cu и как один компилятор nvcc собирает из него код сразу для двух процессоров: центрального и графического. Разбираются флаги компиляции, которые понадобятся во всей траектории, и первая программа «Hello, CUDA!» — дымовой тест окружения с печатью прямо из тредов видеокарты. Для тех, у кого нет карты NVIDIA, — пошаговый рецепт работы в Google Colab с бесплатным GPU. Тренажёр — конструктор команды nvcc: собираете командную строку и смотрите, что она сделает.
Пререквизиты
Базовый C++ (функции, указатели, компиляция из командной строки). Знакомство с общим курсом полезно, но не обязательно: линия C самодостаточна.
Мотивация
Все следующие конспекты линии начинаются одинаково: «скомпилируйте и запустите». Если окружение не настроено, любой пример превращается в загадку: то ли программа неверна, то ли компилятор не найден, то ли карта не поддерживается. Час, потраченный на рабочее место сейчас, экономит его на каждом следующем конспекте — а заодно объясняет, что вообще происходит между нажатием Enter и появлением исполняемого файла, который умеет запускать код на видеокарте.

1. Подойдёт ли ваш компьютер

CUDA — технология NVIDIA, и работает она только на видеокартах NVIDIA. Карты AMD и Intel, а также встроенная графика ноутбуков не подойдут (для них существуют другие технологии — OpenCL, SYCL, — но в этой траектории мы их не касаемся). Хорошая новость: подходит практически любая GeForce, выпущенная за последние десять лет, — от игровых до ноутбучных.

Самый быстрый способ проверить карту — утилита nvidia-smi, которая ставится вместе с драйвером NVIDIA. Откройте терминал (на Windows — PowerShell) и выполните:

> nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 551.86       Driver Version: 551.86       CUDA Version: 12.4    |
|-------------------------------+----------------------+----------------------|
| GPU  Name                     | ...                  | ...                  |
|   0  NVIDIA GeForce RTX 3060 |                      |                      |
+-----------------------------------------------------------------------------+

Здесь важны две вещи: название карты (значит, драйвер её видит) и «CUDA Version» — максимальная версия CUDA, которую поддерживает установленный драйвер. Если команда не найдена — либо нет драйвера NVIDIA, либо нет самой карты.

У каждой карты есть вычислительная способность (compute capability) — номер поколения архитектуры, например 7.5 у GeForce RTX 20xx, 8.6 у RTX 30xx, 8.9 у RTX 40xx. Полная таблица соответствий — на странице developer.nvidia.com/cuda-gpus. Этот номер понадобится при компиляции: он сообщает компилятору, под какое поколение генерировать машинный код.

Нет карты NVIDIA — не беда: раздел 6 показывает, как получить бесплатный GPU в облаке. Все примеры траектории там работают.

2. Установка CUDA Toolkit

CUDA Toolkit — комплект разработчика от NVIDIA: компилятор nvcc, заголовочные файлы, библиотеки и профилировщики. Скачивается с developer.nvidia.com/cuda-toolkit; актуальная линейка — 12.x.

2.1. Windows

Порядок важен:

ШагЧто делатьЗачем
1 Установить Visual Studio Community (бесплатная) с компонентом «Разработка классических приложений на C++». nvcc не компилирует хост-часть программы сам — ему нужен системный компилятор C++. На Windows это cl.exe из Visual Studio.
2 Установить CUDA Toolkit (установщик сам предложит вариант Express). Появятся nvcc, библиотеки и интеграция с Visual Studio; пути пропишутся в PATH автоматически.
3 Открыть терминал x64 Native Tools Command Prompt for VS (ищется в меню «Пуск») и выполнить nvcc -V. Этот терминал знает, где лежит cl.exe. Обычный PowerShell — не знает, и nvcc в нём споткнётся (см. врезку ниже).

Успешная проверка выглядит так:

> nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2024 NVIDIA Corporation
Cuda compilation tools, release 12.4, V12.4.131
Типичная ошибка Компилировать из обычного PowerShell и получить nvcc fatal: Cannot find compiler 'cl.exe' in PATH. Сам nvcc установлен и найден — но ему не найти компилятор Visual Studio, которому он передаёт хост-часть кода. Лечение: работать из «x64 Native Tools Command Prompt» либо добавить каталог с cl.exe (…\VC\Tools\MSVC\…\bin\Hostx64\x64) в PATH.

2.2. Linux

На Linux системный компилятор (gcc/g++) обычно уже есть. Дальше два пути: пакет дистрибутива — sudo apt install nvidia-cuda-toolkit (просто, но версия может отставать) — или репозиторий NVIDIA с сайта Toolkit (свежая версия; установщик даёт точные команды под ваш дистрибутив). Проверка та же: nvcc -V в любом терминале.

3. Что лежит в .cu-файле и что с ним делает nvcc

Программа для видеокарты — это не отдельный проект «только про GPU». В одном файле сосуществуют два вида кода: обычный C++, который выполняет центральный процессор (хост, host), и функции-ядра, которые будут выполняться на видеокарте (устройстве, device). Чтобы компилятор понимал, что перед ним такой «двойной» файл, ему дают расширение .cu.

Команда nvcc — не столько компилятор, сколько дирижёр. Получив .cu-файл, он разделяет код на две части и каждую отправляет по своему конвейеру:

hello.cu хост + device nvcc хост-код (C++) → cl.exe / g++ device-код (ядра) → PTX → SASS hello.exe оба кода внутри

Хост-часть уходит системному компилятору — тому самому cl.exe или g++, ради которого мы ставили Visual Studio. Device-часть NVIDIA компилирует сама: сначала в промежуточный ассемблер PTX (переносимый между поколениями карт), затем в машинный код конкретной архитектуры — SASS. Обе части склеиваются в один исполняемый файл: запускаете вы обычную программу, а код для видеокарты хранится внутри неё и загружается на устройство при первом вызове ядра.

Типичная ошибка Написать CUDA-код в файле .cpp и удивляться сообщениям вроде error: expected an expression на строке запуска ядра. Файлы .cpp nvcc честно компилирует как обычный C++, где тройные угловые скобки <<< >>> — синтаксическая ошибка. Код с ядрами живёт только в .cu.

4. Компиляция: одна команда и четыре полезных флага

Минимальная команда — как у любого компилятора:

nvcc hello.cu -o hello     # Windows создаст hello.exe, Linux — файл hello
./hello                    # запуск (на Windows — hello.exe или просто hello)

Без -o файл получит имя по умолчанию (a.exe на Windows, a.out на Linux) — работает, но быстро захламляет папку безымянными программами. Остальные флаги, которые будут встречаться в траектории:

ФлагЧто делаетКогда нужен
-O2 Оптимизация хост-кода (device-код nvcc оптимизирует по умолчанию). Во всех замерах производительности — иначе сравнение с CPU нечестное.
-arch=sm_86 Целевая архитектура: число — это compute capability без точки (8.6 → sm_86). Вариант -arch=native — «под мою карту». Когда nvcc ругается на устаревшую архитектуру по умолчанию или когда нужна функция нового поколения. Число берётся из таблицы cuda-gpus (раздел 1).
-G Отладочная сборка device-кода: без оптимизаций, с символами для отладчика. Только на время поиска ошибки — код становится в разы медленнее.
-run Скомпилировать и сразу запустить. Быстрые эксперименты из одной команды.

Несколько файлов компилируются так же, как в обычном C++: nvcc main.cu kernels.cu -o app. Предупреждение вида «…architectures are deprecated» — не поломка: nvcc напоминает, что собирает код и под старые поколения карт; явный -arch его убирает.

Тренажёр · конструктор команды nvcc

Соберите команду компиляции и посмотрите, что она сделает. Меняйте настройки — командная строка и прогноз обновляются сразу.

5. «Hello, CUDA!»: дымовой тест

Первая программа обязана быть скучной: её задача — не научить чему-то новому, а подтвердить, что вся цепочка «компилятор → драйвер → карта» живая. Классический вариант — пустое ядро и печать с хоста:

#include <cstdio>

// __global__ — функция-ядро: вызывается с хоста, выполняется на видеокарте
__global__ void kernel()
{
    // пока пусто: нам важен сам факт успешного запуска
}

int main()
{
    kernel<<<1, 1>>>();          // запуск ядра: 1 блок, 1 тред (подробно — в C02)
    printf("Hello, CUDA!\n");   // печатает хост, то есть CPU
    return 0;
}

Если nvcc hello.cu -o hello отработал и программа напечатала строку — окружение готово. Но у этого теста есть слепое пятно: ядро могло вообще не запуститься (например, из-за несовместимой архитектуры), а хост всё равно напечатает своё. Поэтому сразу сделаем тест честнее — заставим говорить саму видеокарту:

#include <cstdio>

__global__ void hello_kernel()
{
    // printf работает и внутри ядра — печатает каждый тред
    printf("Привет от треда %d\n", threadIdx.x);
}

int main()
{
    hello_kernel<<<1, 4>>>();       // 1 блок, 4 треда

    // без этой строки программа может завершиться раньше,
    // чем видеокарта успеет что-то напечатать: запуск ядра асинхронный
    cudaDeviceSynchronize();

    return 0;
}
> nvcc hello.cu -o hello && ./hello
Привет от треда 0
Привет от треда 1
Привет от треда 2
Привет от треда 3

Здесь уже видно главное свойство CUDA: одна функция выполнилась четыре раза — по разу на каждый тред, и каждый тред знает свой номер threadIdx.x. Вызов cudaDeviceSynchronize() заставляет хост дождаться видеокарту: запуск ядра — асинхронная операция, CPU не стоит и не ждёт её завершения. Что такое блоки, треды и откуда берётся их нумерация — тема следующего конспекта.

6. Нет карты NVIDIA: бесплатный GPU в Google Colab

Google Colab выдаёт виртуальную машину с видеокартой (обычно Tesla T4) бесплатно — и на ней уже установлен CUDA Toolkit. Компилировать C++ там можно прямо из блокнота:

ШагДействие
1Открыть colab.research.google.com, создать блокнот; в меню «Среда выполнения → Сменить среду выполнения» выбрать аппаратный ускоритель «T4 GPU».
2Проверить карту и компилятор: в ячейках выполнить !nvidia-smi и !nvcc -V (восклицательный знак запускает команду терминала).
3Записать код в файл: ячейка, начинающаяся с %%writefile hello.cu, сохраняет весь свой текст в файл.
4Скомпилировать и запустить: !nvcc hello.cu -o hello -arch=sm_75, затем !./hello (у T4 compute capability 7.5).

Ограничения бесплатного Colab: сессия живёт несколько часов и сбрасывается, файлы исчезают вместе с ней (храните код в блокноте, а не только в файлах), GPU выдаётся не мгновенно. Для учебных задач траектории этого достаточно с запасом — все примеры линии C собираются и работают в Colab без изменений.

Контрольные вопросы

Благодарность Линия C этой траектории опирается на курс «Программирование CUDA» Лаборатории суперкомпьютерных и квантовых вычислений ДВФУ — https://cc.dvfu.ru/.

Источники

  1. CUDA Installation Guide for Microsoft Windows // NVIDIA Docs : [сайт]. — URL: https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/ (дата обращения: 09.07.2026).
  2. CUDA Installation Guide for Linux // NVIDIA Docs : [сайт]. — URL: https://docs.nvidia.com/cuda/cuda-installation-guide-linux/ (дата обращения: 09.07.2026).
  3. CUDA C++ Programming Guide // NVIDIA Docs : [сайт]. — URL: https://docs.nvidia.com/cuda/cuda-c-programming-guide/ (дата обращения: 09.07.2026).
  4. Your GPU Compute Capability // NVIDIA Developer : [сайт]. — URL: https://developer.nvidia.com/cuda-gpus (дата обращения: 09.07.2026).
  5. NVCC — CUDA Compiler Driver // NVIDIA Docs : [сайт]. — URL: https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/ (дата обращения: 09.07.2026).