3.3 Технология NVIDIA CUDA Compute Unified Device Architecture Технология CUDA — это программно-аппаратная вычислительная архитектура NVIDIA, основанная на расширении языка Си, которая даёт возможность организации доступа к набору инструкций графического ускорителя и управления его памятью при организации параллельных вычислений. Графические процессоры видеоускорителей GeForce восьмого поколения и старше (серии GeForce 8, GeForce 9, GeForce 200), а также Quadro и Tesla. 1 Основные характеристики CUDA: - унифицированное программно-аппаратное решение для параллельных вычислений на видеочипах NVIDIA; - большой набор поддерживаемых решений, от мобильных до мультичиповых; - стандартный язык программирования Си; - стандартные библиотеки численного анализа FFT (быстрое преобразование Фурье) и BLAS (линейная алгебра); - оптимизированный обмен данными между CPU и GPU; - взаимодействие с графическими API OpenGL и DirectX; - поддержка 32- и 64-битных операционных систем: Windows, Linux и MacOS X; - возможность разработки на низком уровне. 2 3 3.4 Среда программирования 4 5 CUBLAS — CUDA вариант BLAS (Basic Linear Algebra Subprograms), предназначенный для вычислений задач линейной алгебры и использующий прямой доступ к ресурсам GPU; CUFFT — CUDA вариант библиотеки Fast Fourier Transform для расчёта быстрого преобразования Фурье, широко используемого при обработке сигналов. Поддерживаются следующие типы преобразований: complex-complex (C2C), real-complex (R2C) и complex-real (C2R). 6 Среда разработки CUDA (CUDA Toolkit) включает: - компилятор nvcc; - библиотеки FFT и BLAS; - профилировщик; - отладчик gdb для GPU; - CUDA runtime драйвер в комплекте стандартных драйверов NVIDIA; - руководство по программированию; CUDA Developer SDK (исходный код, утилиты и документация). 7 Примеры программ, приведенные в руководстве: - параллельная битональная сортировка (bitonic sort), - транспонирование матриц, - параллельное префиксное суммирование больших массивов, - свёртка изображений, - дискретное вейвлет-преобразование, - пример взаимодействия с OpenGL и Direct3D, - использование библиотек CUBLAS и CUFFT, - параллельный генератор случайных чисел Mersenne Twister, - вычисление гистограммы большого массива. 8 Модель программирования в CUDA предполагает группирование потоков. Потоки объединяются в блоки потоков (thread block) — одномерные или двумерные сетки потоков, взаимодействующих между собой при помощи разделяемой памяти и точек синхронизации. Программа (ядро, kernel) исполняется над сеткой (grid) блоков потоков (thread blocks), см. рисунок ниже. Одновременно исполняется одна сетка. Каждый блок может быть одно-, двух- или трехмерным по форме, и может состоять из 512 потоков на текущем аппаратном обеспечении. 9 10 Блоки потоков выполняются в виде небольших групп, называемых варп (warp), размер которых — 32 потока. Это минимальный объём данных, которые могут обрабатываться в мультипроцессорах. И так как это не всегда удобно, CUDA позволяет работать и с блоками, содержащими от 64 до 512 потоков. Группировка блоков в сетки позволяет уйти от ограничений и применить ядро к большему числу потоков за один вызов. 11 3.5 Модель памяти CUDA 12 Глобальная память — самый большой объём памяти, доступный для всех мультипроцессоров на видеочипе, размер составляет от 256 мегабайт до 1.5 гигабайт в обычных видеокартах и до 4 Гбайт на Tesla. Локальная память — это небольшой объём памяти, к которому имеет доступ только один потоковый процессор. Разделяемая память — это 16-килобайтный (в видеочипах нынешней архитектуры) блок памяти с общим доступом для всех потоковых процессоров в мультипроцессоре. Эта память весьма быстрая, такая же, как регистры. Она обеспечивает взаимодействие потоков, управляется разработчиком напрямую и имеет низкие задержки. Память констант — область памяти объемом 64 килобайта, доступная только для чтения всеми мультипроцессорами. Она кэшируется по 8 килобайт на каждый мультипроцессор. Текстурная память — блок памяти, доступный для чтения всеми мультипроцессорами. 13 14 Типичный шаблон решения задач: • задача разбивается на подзадачи; • входные данные делятся на блоки, которые вмещаются в разделяемую память; • каждый блок обрабатывается блоком потоков; • подблок подгружается в разделяемую память из глобальной; • над данными в разделяемой памяти проводятся соответствующие вычисления; • результаты копируются из разделяемой памяти обратно в глобальную. 15