Исследование возможностей CUDA-технологий параллельных вычислений

  1. В начале лета 2012 г. Баканов В.М. (после периода увлечения кла́стерными технологиями параллельных вычислений и архитектурой пото́ковых (DATA-FLOW) вычислителей) заинтересовался возможностями массивно-параллельных вычислений на графических картах фирмы NVIDIA.

  2. Технология CUDA (Compute Unified Device Architecture) основана на использовании ресурсов видеокарт (графических ускорителей) фирмы NVIDIA, работающих в архитектуре SIMD (Single Instruction - Multiple Data) в качестве свербыстродействующих арифметических сопроцессоров (GPU - Graphic Processor Unit) в дополнение к CPU (Central Processor Unit); в результате возникло направление GPGPU (General-Purpose commuting on Graphics Processing Units). Технология CUDA является естественным развитием всеме́рного повышения вычислительных мощносте́й видеокарт в целях обработки сложных видеосцен (игры, промышленные симуляторы). В настоящее время GPU используются даже для повышения вычислительных мощностей суперкомпьютеров (китайский Tianhe-1A производительностью 2,57 Pflops включает наряду с 14'336 многоядерными процессорами Intel Xeon еще и 7'168 графических процессоров NVIDIA Tesla M2050. Подобные GPU легко встраиваются в персональные компьютеры (ПК); в этом случае из вычислительная мощность повышается многократно. Фирма NVIDIA разработала бесплатное программное обеспечение (ПО) для поддержки направления GPGPU (developer.nvidia.com); благодаря чему создание ПО для GPU по трудоемкости сравни́мо с таковым для CPU.
       В настоящее время в Москве несколько ВУЗ'ов (в первую очередь МГУ и МГТУ им Н.Э.Баумана) на постоянной основе ведут обучение основам CUDA (см., например, здесь; более подробный список - тут).

  3. Данное оборудование представляет собой графическую карту (обычно двойной ширины), вставляемую в слот шины PCI Express 2.0 персонального компьютера достаточной мощности (поддерживаются архитектуры 32 и 64 бит). С целью повышения вычислительной мощности возможно комплексирование карт по технологии SLI (Scalable Link Interface, ru.wikipedia.org/wiki/NVIDIA_SLI). Для работы с вещественными числами (требование задач математического моделирования) двойной точности (double) требуется карта с т.н. Compute Capability (вычислительные возможности) 1.3 и выше - см. developer.nvidia.com/cuda-gpus); для поддержки атома́рных функций операций с 64-битовыми целыми числами в разделяемой памяти и 32-битовыми вещественными в глобальной и разделяемой памяти необходимо иметь карту с вычислительными возможностями 2.1 или выше.
       Потребляемая картой мощность значительна (200 W и более), поэтому требуется блок питания ПК мощностью не менее 500 W (большинство современных ПК обладает такими блоками питания, однако проверить не помешает). Внешняя шина для подключения - PCI Express x16 (в современных motherboards обычно имеется один или два таких слота). Длина платы - до 230÷250 мм (полезно проверить, позволяет ли корпус установить плату такой длины).
       При создании ПО для CUDA используется среда MS VS C++ версии не хуже 2005 (при соответствующей настройке), специализированное системное ПО бесплатно (developer.nvidia.com/cuda-downloads) и включает набор библиотек для операций линейной алгебры, обработки сигналов и др. (developer.nvidia.com/cuda-tools-ecosystem).
       Графические ускорители с поддержкой CUDA выпускаются многими производителями; автор с мая 2012 г. использует недорогую (стоимость в пределах 8 тыс. руб.) карту на основе набора GTX 560 Ti (напр., www.thg.ru/graphic/geforce_gtx560ti/print.html).

  4. Первым этапом явилась (бесплатная) вы́грузка и установка инструментария разработчика - фирменного программного обеcпечения фирмы NVIDIA - CUDA Toolkit, CUDA Drivers и CUDA SDK с адреса developer.nvidia.com/cuda/cuda-downloads (имеются варианты для Windows7/Vista/XP и Linux различных клонов 32- и 64-bit и Mac). После этого изучалась готовые образцы программ (в исходных текстах и откомпилированные под 32- и 64-х разрядные системы, просматривлась документация.
       В качестве компилятора с С/С++ для CPU использовался MS Visual Studio 2005 (бесплатная версия); компилятор CUDA-программ для GPU nvcc уже содержится в вы́груженном программном обеспечении (CUDA Toolkit). Утилита nvcc в исходном .CU файле разделяет код для GPU и CPU и первый компилирует самостоятельно, а для компиляции второго вызывает MS VS (управляющей средой является, однако, MS VS). Для реализации такого режима следует задать для MS VS правила компиляции .CU-файлов (такой файл Cuda.Rules уже имеется в выгруженном CUDA SDK). В данном случае, однако, использовался альтернативный вариант проекта CUDA VS Wizard (бесплатная вы́грузка с ресурса sourceforge.net/projects/cudavswizard, добавляющего к MS VS новый тип проекта). Заметим, что сказанное верно для версии CUDA Toolkit 4.2 (April 2012, сейчас находится в архиве по адресу developer.nvidia.com/cuda-toolkit-42-archive); последней версией является 5.0 (October 2012, в неё CUDA VS Wizard уже интегрирован).
       Далее последовательно создавались, отлаживались и компилировалсь несложные CUDA-программы (исходные тексты здесь):

    • SAMPLE_00.CU - вывод на консоль параметров установленных графических карт.
    • SAMPLE_01.CU - возвра́т из GPU (с последующей распечаткой на консо́ли из CPU) классического текста "Hello, world!..".
    • SAMPLE_02.CU - тестирование GPU операцией перемножения двух вещественныx чисел с использованием 1 блока (block) и 1 нити (thread) в нём (т.е. вызовом функции ядра вида <<<1,1>>>).
    • SAMPLE_03.CU - тестирование GPU операцией сложения двух матриц вещественныx чисел с использованием N блоков (block) по 1 нити (thread) в каждом (вызов функции ядра вида <<<N,1>>> с последующим сравнением корректности выполнения GPU-операций путём сопоставления с результатами выполнения таких же операций на CPU).
    • SAMPLE_04.CU - то же самое, что SAMPLE_03.CU, но с использованием вызова ядра вида <<<1,N>>> .
    • SAMPLE_05.CU - то же самое, но с использоваием K блоков (block) и M нитей (thread) на GPU (вызов функции ядра вида <<<K,M>>>) .
    • SAMPLE_06.CU - сопоставление времени перемножения двух квадратных матриц вещественных чисел на GPU блоками 16×16 при использовании только глобальной (global) памяти и CPU.
    • SAMPLE_07.CU - вариант программы SAMPLE_06.CU с использованием разделя́емой (shared) памяти на GPU.

  5. Время выполнения операции перемножения 
матриц на GPU и CPU (опыты 08.VII.2012) Следующим этапом исследований явилось определение реального повышения производительности GPU (автор использовал карту на основе процессора GTX 560 Ti) по сравнению с GPU (у автора - 4-х ядерный процессор Intel Core i5-2320 Sandy Bridge 3,0 GHz с кэшем уровня L1 размером 32 kB для данных + 32 kB для инструкций на каждое ядро, кэшем L2 256 kB для каждого ядра и кэшем L3 6 МB и оперативная память 8 GB; операционная среда - Windows Home Basic 7 SP1 64-bit, компилятор MS Visual Studio 2005).
       Исследования производились на процедуре перемножения матриц (блоками 16×16 элементов матриц) согласно книге [I]; результаты эксперимента приведены на рис. справа. Порядок квадратных перемножаемых матриц устанавливался равным 512, 1024, 2048, 3072 и 4096 для действительных чисел форматов float и double; при этом за время выполнения операции на GPU принималось не только время собственно умножения, но учитывались и время загру́зки данных на GPU и время обратной вы́грузки. Для замера времени применялась C-функция ftime() вместо специфического для CUDA метода, основанного на событиях (CUDA events). Такой подход оправда́н в том случае, когда результат операции на GPU является конечной целью вычислительного процесса (и неприе́млем, конечно, для варианта дальнейшй обработки на GPU). Ускорение вычислений на GPU по отношению к CPU
       Для CPU была распи́сана стандартная классическая схема (гнездо циклов уровня 3) умножения матриц; при этом возможности SSE (Streaming SIMD Extensions) не использовались.
       Ускорение (убыстре́ние) процесса вычислений определялось простым отношением времени выполнения операции умножения на CPU и GPU; данные для чисел различного формата и порядка перемножаемых матриц приведены слева. Видно, что ускорение вычислений может достигать многосоткратной величины (при использовании SSE на CPU - меньше, конечно) и мало зависит от типа (float или double) данных (согласно [I] арифметические операции всегда выполняются над данными типа double); снижение интенсивности роста ускорения по мере увеличения порядка матриц связано, по-видимому, с возрастанием доли времени на обмен данными между CPU и GPU.
       Утилита CUDA-Z для этой карты показывает производительность для double в 105 Glop/s, а для float - 839 Glop/s. Значит, при использовании специфических для float функций __fadd_ и __fmul_ следует ожидать ещё большего роста производительности GPU.
       Т.о. автор на опыте убедился в существенном убыстре́нии вычислений при использовании GPU и технологии CUDA и намерен применять их в собственных разработках программного обеспечения.

  6. В качестве литературных источников по развертыванию и использованию технологии CUDA можно рекомендовать:

    1. Боресков А.В., Харламов А.А. Основы работы с технологией CUDA (+ CD). —M.: ДМК Пресс, 2011. -232 c. (выгрузить; убрано по требованию Агентства авторской безопасности).
    2. Сандерс Дж., Кэндрот Э. Технология CUDA в примерах: введение в программирование графических процессоров (пер. c англ.). —M.: ДМК Пресс, 2011. -232 c.

    C иными книгами Борескова А.В. также полезно ознакомиться..

Возврат к главной странице сайта Возврат к главной странице