Что такое CUDA? Параллельное программирование для графических процессоров

CUDA - это платформа параллельных вычислений и модель программирования, разработанная Nvidia для общих вычислений на собственных графических процессорах (графических процессорах). CUDA позволяет разработчикам ускорять приложения с интенсивными вычислениями, используя мощность графических процессоров для параллелизируемой части вычислений.

Хотя были и другие предложенные API для графических процессоров, такие как OpenCL, и есть конкурирующие графические процессоры других компаний, таких как AMD, комбинация графических процессоров CUDA и Nvidia доминирует в нескольких областях приложений, включая глубокое обучение, и является основой для некоторых из них. самые быстрые компьютеры в мире.

Графические карты, возможно, такие же старые, как и ПК, то есть, если вы считаете, что адаптер IBM Monochrome Display Adapter 1981 года является графической картой. К 1988 году вы могли получить 16-битную карту 2D VGA Wonder от ATI (компания в конечном итоге была приобретена AMD). К 1996 году у 3dfx Interactive можно было купить ускоритель 3D-графики, чтобы запускать шутер от первого лица Quake на полной скорости.

Также в 1996 году Nvidia начала пытаться конкурировать на рынке 3D-ускорителей со слабыми продуктами, но по ходу дела усвоила и в 1999 представила успешную GeForce 256, первую видеокарту, которая будет называться GPU. В то время основной причиной наличия графического процессора были игры. Только позже люди использовали графические процессоры в математике, науке и инженерии.

Происхождение CUDA

В 2003 году группа исследователей во главе с Яном Баком представила Brook, первую широко распространенную модель программирования, расширяющую C с помощью конструкций, параллельных данным. Позже Бак присоединился к Nvidia и в 2006 году возглавил запуск CUDA, первого коммерческого решения для универсальных вычислений на графических процессорах.

OpenCL против CUDA

Конкурент CUDA OpenCL был запущен Apple и Khronos Group в 2009 году в попытке предоставить стандарт для гетерогенных вычислений, который не ограничивался процессорами Intel / AMD с графическими процессорами Nvidia. Хотя OpenCL звучит привлекательно из-за своей универсальности, он не работает так же хорошо, как CUDA на графических процессорах Nvidia, и многие фреймворки глубокого обучения либо не поддерживают его, либо поддерживают его только после того, как была выпущена их поддержка CUDA.

Повышение производительности CUDA

CUDA улучшила и расширила свои возможности с годами, более или менее синхронно с улучшенными графическими процессорами Nvidia. Начиная с CUDA версии 9.2, используя несколько серверных графических процессоров P100, вы можете добиться 50-кратного повышения производительности по сравнению с процессорами. V100 (не показан на этом рисунке) еще в 3 раза быстрее при некоторых нагрузках. Предыдущее поколение серверных графических процессоров, K80, предлагало прирост производительности от 5 до 12 раз по сравнению с процессорами.

Nvidia

Увеличение скорости за счет графических процессоров произошло как раз в самый последний момент для высокопроизводительных вычислений. Повышение однопоточной производительности процессоров с течением времени, которое, согласно закону Мура, будет удваиваться каждые 18 месяцев, замедлилось до 10 процентов в год, поскольку производители микросхем столкнулись с физическими ограничениями, включая ограничения размера на разрешение маски микросхемы и выход микросхемы в процессе производства. и ограничения тепла на тактовых частотах во время работы.

Nvidia

Домены приложений CUDA

Nvidia

Графические процессоры CUDA и Nvidia были приняты во многих областях, где требуется высокая производительность вычислений с плавающей запятой, как показано на картинке выше. Более полный список включает:

  1. Вычислительные финансы
  2. Моделирование климата, погоды и океана
  3. Наука о данных и аналитика
  4. Глубокое обучение и машинное обучение
  5. Оборона и разведка
  6. Производство / AEC (архитектура, проектирование и строительство): CAD и CAE (включая вычислительную гидродинамику, вычислительную механику конструкций, проектирование и визуализацию, а также автоматизацию электронного проектирования)
  7. Мультимедиа и развлечения (включая анимацию, моделирование и рендеринг; цветокоррекцию и управление зернистостью; композитинг; окончательная обработка и эффекты; редактирование; кодирование и цифровое распространение; эфирная графика; инструменты для съемки, просмотра и стерео; а также погодная графика)
  8. Медицинская визуализация
  9. Нефть и газ
  10. Исследования: высшее образование и суперкомпьютеры (включая вычислительную химию и биологию, численную аналитику, физику и научную визуализацию)
  11. Безопасность и охрана
  12. Инструменты и управление

CUDA в глубоком обучении

Глубокое обучение имеет огромную потребность в скорости вычислений. Например, для обучения моделей для Google Translate в 2016 году команды Google Brain и Google Translate выполнили сотни однонедельных прогонов TensorFlow с использованием графических процессоров; Для этой цели они купили у Nvidia 2000 графических процессоров серверного уровня. Без графических процессоров эти учебные прогоны заняли бы месяцы, а не неделю. Для производственного развертывания этих моделей перевода TensorFlow Google использовал новый пользовательский чип обработки, TPU (модуль обработки тензора).

Помимо TensorFlow, многие другие инфраструктуры DL полагаются на CUDA для поддержки своих графических процессоров, включая Caffe2, CNTK, Databricks, H2O.ai, Keras, MXNet, PyTorch, Theano и Torch. В большинстве случаев они используют библиотеку cuDNN для глубоких вычислений нейронной сети. Эта библиотека настолько важна для обучения фреймворков глубокого обучения, что все фреймворки, использующие данную версию cuDNN, имеют практически одинаковые показатели производительности для эквивалентных вариантов использования. Когда CUDA и cuDNN улучшаются от версии к версии, все платформы глубокого обучения, обновляющиеся до новой версии, видят прирост производительности. Производительность от фреймворка к фреймворку может отличаться в зависимости от того, насколько хорошо они масштабируются на несколько графических процессоров и несколько узлов.

CUDA программирование

Nvidia

Набор инструментов CUDA

CUDA Toolkit включает библиотеки, инструменты отладки и оптимизации, компилятор, документацию и библиотеку времени выполнения для развертывания ваших приложений. В нем есть компоненты, которые поддерживают глубокое обучение, линейную алгебру, обработку сигналов и параллельные алгоритмы. В целом библиотеки CUDA поддерживают все семейства графических процессоров Nvidia, но лучше всего работают с последним поколением, таким как V100, который может быть в 3 раза быстрее, чем P100, для рабочих нагрузок глубокого обучения. Использование одной или нескольких библиотек - самый простой способ воспользоваться преимуществами графических процессоров, если необходимые вам алгоритмы реализованы в соответствующей библиотеке.

Nvidia

Библиотеки глубокого обучения CUDA

В сфере глубокого обучения есть три основных библиотеки с ускорением на GPU: cuDNN, о которой я упоминал ранее как компонент GPU для большинства платформ глубокого обучения с открытым исходным кодом; TensorRT - высокопроизводительный оптимизатор логических выводов и среда выполнения от Nvidia; и DeepStream, библиотека вывода видео. TensorRT помогает оптимизировать модели нейронных сетей, откалибровать для снижения точности с высокой точностью и развернуть обученные модели в облаках, центрах обработки данных, встроенных системах или платформах автомобильных продуктов.

Nvidia

Библиотеки линейной алгебры и математики CUDA

Линейная алгебра лежит в основе тензорных вычислений и, следовательно, глубокого обучения. BLAS (базовые подпрограммы линейной алгебры), набор матричных алгоритмов, реализованных в Фортране в 1989 году, с тех пор используется учеными и инженерами. cuBLAS - это версия BLAS с ускорением на графическом процессоре и самый высокопроизводительный способ выполнения матричной арифметики с помощью графических процессоров. cuBLAS предполагает, что матрицы плотные; cuSPARSE обрабатывает разреженные матрицы.

Nvidia

Библиотеки обработки сигналов CUDA

Быстрое преобразование Фурье (БПФ) - один из основных алгоритмов, используемых для обработки сигналов; он превращает сигнал (например, звуковую волну) в спектр частот. cuFFT - это БПФ с ускорением на GPU.

Кодеки, использующие такие стандарты, как H.264, кодируют / сжимают и декодируют / распаковывают видео для передачи и отображения. SDK видеокодеков Nvidia ускоряет этот процесс с помощью графических процессоров.

Nvidia

Библиотеки параллельных алгоритмов CUDA

Все три библиотеки для параллельных алгоритмов имеют разные цели. NCCL (библиотека коллективных коммуникаций Nvidia) предназначена для масштабирования приложений на несколько графических процессоров и узлов; nvGRAPH - для параллельной графической аналитики; и Thrust - это библиотека шаблонов C ++ для CUDA, основанная на стандартной библиотеке шаблонов C ++. Thrust предоставляет богатый набор параллельных примитивов данных, таких как сканирование, сортировка и сокращение.

Nvidia

CUDA против производительности процессора

В некоторых случаях вы можете использовать вставляемые функции CUDA вместо эквивалентных функций ЦП. Например, подпрограммы умножения матриц GEMM из BLAS можно заменить версиями GPU, просто подключившись к библиотеке NVBLAS:

Nvidia

Основы программирования CUDA

Если вы не можете найти подпрограммы библиотеки CUDA для ускорения ваших программ, вам придется попробовать свои силы в программировании CUDA низкого уровня. Сейчас это намного проще, чем было, когда я впервые попробовал это в конце 2000-х. Среди других причин - более простой синтаксис и доступные инструменты разработки лучше. Моя единственная придирка заключается в том, что в MacOS последний компилятор CUDA и последний компилятор C ++ (из Xcode) редко синхронизируются. Нужно загрузить старые инструменты командной строки от Apple и переключиться на них, xcode-selectчтобы получить код CUDA для компиляции и компоновки.

Например, рассмотрим эту простую процедуру C / C ++ для добавления двух массивов:

void add (int n, float * x, float * y)

{  

       для (int i = 0; i <n; i ++)      

             у [я] = х [я] + у [я];

}

Вы можете превратить его в ядро, которое будет работать на графическом процессоре, добавив __global__ключевое слово в объявление, и вызвать ядро, используя синтаксис с тройными скобками:

добавить << >> (N, x, y);

Вы также должны изменить свои malloc/ newи free/ deleteвызовы на cudaMallocManagedи cudaFreeтак, чтобы вы выделяли место на графическом процессоре. Наконец, вам нужно дождаться завершения расчета графического процессора, прежде чем использовать результаты в процессоре, что вы можете выполнить с его помощью cudaDeviceSynchronize.

В тройной скобке выше используется один блок с резьбой и одна резьба. Современные графические процессоры Nvidia могут обрабатывать множество блоков и потоков. Например, графический процессор Tesla P100 на основе архитектуры графического процессора Pascal имеет 56 потоковых мультипроцессоров (SM), каждый из которых может поддерживать до 2048 активных потоков.

Коду ядра необходимо знать индекс своего блока и потока, чтобы найти его смещение в переданных массивах. Распараллеленное ядро ​​часто использует цикл с шагом сетки , например следующий:

__Глобальный__

void add (int n, float * x, float * y)

{

   int index = blockIdx.x * blockDim.x + threadIdx.x;

   int stride = blockDim.x * gridDim.x;

   for (int i = index; i <n; i + = шаг)

     у [я] = х [я] + у [я];

}

Если вы посмотрите на примеры в CUDA Toolkit, вы увидите, что нужно учитывать не только основы, которые я рассмотрел выше. Например, некоторые вызовы функций CUDA необходимо заключить в checkCudaErrors()вызовы. Кроме того, во многих случаях самый быстрый код будет использовать библиотеки, такие как cuBLASраспределение памяти хоста и устройства и копирование матриц туда и обратно.

Таким образом, вы можете ускорить свои приложения с помощью графических процессоров на многих уровнях. Вы можете написать код CUDA; вы можете вызывать библиотеки CUDA; и вы можете использовать приложения, которые уже поддерживают CUDA.