Современные информационные технологии /2. Вычислительная техника и программирование

 

Аспирант Лунин Д.В., д.т.н., проф. Скворцов С.В.

Рязанский государственный радиотехнический университет, Россия

Параллельные вычисления на платформе CUDA

 

Интерес к использованию графических ускорителей в качестве средств высокопроизводительных вычислений поддерживается усилиями ведущих разработчиков аппаратуры. Так, компания nVidia предоставляет платформу CUDA [1] для вычислений на графическом ускорителе. Аналогично, компания AMD выступила с инициативой Stream [2].

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

Таким образом, задача организации вычислений средствами графических ускорителей, является актуальной и новой по сравнению как с последовательным программированием, так и с многопоточным параллельным программированием [3,4]. Многие аспекты этой задачи требуют достаточно низкоуровневой реализации и оптимизации кода, подобно методам и алгоритмам, изложенным в работах  [10-12].

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

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

Программа для графического ускорителя, написанная на платформе CUDA, разделяется на две части: код для исполнения на графическом устройстве (device code) и код для исполнения на центральном процессоре (host code). Код для исполнения на графическом устройстве (device) может быть написан как на специальном низкоуровневом языке (PTX), так и на расширении языка Си (Си для CUDA). В последнем случае ядро имеет вид функции языка Си, описывающей поведение одного потока.

При создании приложений, программист имеет возможность задавать количество блоков и потоков. Оптимальным является использование от 64 до 512 потоков в блоке. Группировка блоков в сетки позволяет применить ядро к большему числу потоков за один вызов. Это помогает и при масштабировании. Если у графического процессора недостаточно ресурсов, он будет выполнять блоки последовательно. В обратном случае, блоки могут выполняться параллельно, что важно для оптимального распределения работы на видеоплатах разного уровня.

В качестве практического примера использования CUDA разработана программа умножения двух матриц на графическом ускорителе. Пусть исходные матрицы А и В являются квадратными и имеют размер n*n. Результирующая матрица C будет иметь такой же размер.

Для организации параллельного умножения матриц A и B представим результат - матрицу С в виде совокупности квадратных подматриц размером BLOCK_SIZE*BLOCK_SIZE таким образом, чтобы вычисление всех элементов каждой подматрицы производилось бы последовательно в одном потоке (thread). Все подобные потоки, сформированные в среде CUDA, выполняются параллельно аппаратными средствами графического ускорителя (device).

Для оценки эффекта от применения распараллеливающих преобразований на платформе CUDA были проведены измерения скорости работы двух программ умножения матриц: последовательная реализация на ЦП; многопоточная реализация на базе графического ускорителя (ГУ). При этом вторая версия программы запускалась на выполнение с тремя вариантами параметров ядра для значений BLOCK_SIZE = 16; 32; 64; 128.

При проведении экспериментов использовались следующие аппаратные средства: ЦП Intel Core-i7; видеоплата nVidia Quadro FX1800 с памятью 1 ГБ. Для каждого размера матрицы выполнено по 10 опытов с разными исходными данными. Полученные результаты представлены в таблице 1.

Таблица 1 – Среднее время умножения квадратных матриц (мс)

Программа

умножения матриц

Порядок матрицы n

256

512

1024

Последовательная на ЦП

66

588

6621

Многопоточная на ГУ

(BLOCK_SIZE = 16)

21

167

1318

Многопоточная на ГУ

(BLOCK_SIZE = 32)

2.35

6.32

10.73

Многопоточная на ГУ

(BLOCK_SIZE = 64)

0.53

1.33

4.26

Многопоточная на ГУ

(BLOCK_SIZE = 128)

0.86

1.52

4.69

Полученные результаты показывают, что использование графического ускорителя позволяет значительно увеличить скорость работы многопоточных программ. Так при n = 1024 время выполнения многопоточной версии программы по сравнению с последовательной однопоточной сокращается примерно в 300 раз. Для матриц, состоящих из небольшого числа элементов, выигрыш составляет около 40 раз. Важно отметить, что скорость работы многопоточной программы сильно зависит от параметра BLOCK_SIZE, значение которого должно выбираться экспериментально.

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

 

Литература:

1. CUDA Parallel Computing Platform. [Электронный ресурс]. URL: http://www.nvidia.com/cuda (дата обращения 28.03.14).

2. AMD Quick Stream Technology. [Электронный ресурс]. URL: http://www.amd.com/es/solutions/software/pages/quick-stream-technology.aspx (дата обращения 28.03.14).

3. Камерон Х., Трейси Х. Параллельное и распределенное программирование с использованием C++. М.: Вильямс, 2004. 672 с.

4. Эндрюс Г. Основы многопоточного, параллельного и распределенного программирования. М.: ИД ”Вильямс”, 2003. 512 с.

5. Козлов М.А., Скворцов С.В. Алгоритмы параллельной сортировки данных и их реализация на языке Clojure // Вестник Рязанского государственного радиотехнического университета. 2013. № 4-1 (46). С. 92-96.

6. Першин А.С., Скворцов С.В. Распределение регистровой памяти в системах параллельной обработки данных // Системы управления и информационные технологии. 2007. № 1 (27). С. 65-70.

7. Рудаков В.Е., Скворцов С.В. Построение базового множества независимых путей потокового графа для тестирования программных модулей // Системы управления и информационные технологии. 2012. Т. 50. № 4. С. 67-70.

8. Михеева Л.Б., Скворцов С.В. Синтез параллельного кода для RISC-процессоров с оптимизацией загрузки регистровой памяти // Информационные технологии. 2002. № 7. С. 2-9.