Лабораторная работа №1 “Обработка одномерных массивов и матриц при помощи CUDA”

advertisement
стр. 1
(С) Павлий В.А., кафедра КСМ, ДонНТУ, 2014
Лабораторная работа №1
“Обработка одномерных массивов и матриц при помощи CUDA”
Цель работы: научиться использовать современную
параллельного программирования CUDA для обработки
массивов и матриц.
технологию
одномерных
Теоретическая часть
В разработке. Для выполнения данной работы можно пользоваться
источником Сандерс Дж., Кендрот Э. “Технология CUDA в примерах”, гл. 1
– 4, стр. 16 – 58.
Задание и порядок выполнения лабораторной работы
Часть 1. Установка требуемого программного обеспечения
1.1 Установка MS Visual Studio
Для работы с технологией CUDA потребуется MS Visual Studio. Самую
последнюю версию среды лучше не использовать, так как существует
вероятность того, что последний комплект ПО CUDA ее еще не
поддерживает. На момент написания этих методических указаний студентам
лучше использовать Visual Studio 2005 – Visual Studio 2012.
Заметим попутно, что для учебных целей нет разницы в использовании
Professional или Express версии Visual Studio. Для работы с CUDA
необходимо, чтобы среда поддерживала компиляцию программ на языке
С/С++. Поэтому, если Вы устанавливаете Professional версию, проблем, как
правило, не бывает. При установке Express версии нужно обращать внимание
на поддерживаемый язык и тип Вашей операционной системы (32 или 64
разряда). Express версию можно скачать бесплатно с сайта Microsoft по
ссылке:
[http://www.visualstudio.com/downloads/download-visual-studio-vs]
1.2 Установка CUDA Developer Drivers, CUDA Toolkit, GPU
Computing SDK
После установки MS Visual Studio необходимо установить CUDA
Developer Drivers, CUDA Toolkit, GPU Computing SDK. Технология CUDA
была разработана компанией NVIDIA для ускорения вычислений при
обработке графики за счет параллельной обработки данных. Принято
считать, что указанная технология поддерживается во всех видеокартах
NVIDIA, выпущенных после 2007 года. Поэтому если у Вас именно такая
видеокарта – Вы сможете почувствовать настоящую мощь параллельных
вычислений. Окончательно убедиться в том, что Ваша видеокарта
поддерживает технологию CUDA можно на сайте производителя.
стр. 2
(С) Павлий В.А., кафедра КСМ, ДонНТУ, 2014
Однако если у Вас нет подходящего оборудования, изучить указанную
технологию и научиться писать программы для CUDA все равно можно.
Правда “почувствовать мощь” уже не получится.
Этапы дальнейшей установки будут несколько отличаться для
конфигурации с установленной на машине видеокартой от NVIDIA и без нее.
►Для конфигурации ПК с видеокартой от NVIDIA нужно зайти на
страницу загрузки программного обеспечения для CUDA,
[https://developer.nvidia.com/cuda-toolkit-archive]
перейти с нее на страницу с последней версией (на момент написания
это версия 6.5), скачать и установить на свой компьютер. Начиная с версии
5.0 все три пакета, которые необходимы для программирования под CUDA, –
CUDA Developer Drivers, CUDA Toolkit, GPU Computing SDK – объединены
в один инсталлятор, что, конечно же, очень удобно. При загрузке обращайте
внимание на версию и тип Вашей операционной системы. При установке не
используйте длинных путей, содержащих русские буквы, а по возможности
короткие пути. Это пригодится впоследствии при интеграции этих пакетов в
Visual Studio.
►Для конфигурации ПК без видеокарты от NVIDIA нужно зайти на
страницу загрузки программного обеспечения для CUDA,
[https://developer.nvidia.com/cuda-toolkit-archive]
перейти с нее на страницу с версией 2.3, скачать и установить CUDA
Toolkit, GPU Computing SDK. В отличие от первого варианта конфигурации,
пакет CUDA Developer Drivers не нужен, так как у Вас нет соответствующего
оборудования. Собственно, он даже не установится.
При скачивании пакетов обращайте также внимание на версию и тип
Вашей операционной системы.
При установке CUDA Toolkit, GPU Computing SDK постарайтесь
использовать короткие пути без русских букв. Это пригодится впоследствии
при интеграции этих пакетов в Visual Studio. Наиболее оптимальный вариант
– использовать следующие пути установки:
[С:\CUDA\TOOLKIT],
[С:\CUDA\SDK].
Почему необходимо устанавливать ПО CUDA именно версии 2.3? Дело
в том, что именно данная версия – последняя в линейке ПО CUDA, в которой
есть поддержка режима эмуляции. Следовательно, если включить данный
режим в настройках проекта (об этом речь далее), то компилировать и
исполнять программный код CUDA можно и без реального устройства,
поддерживающего технологию CUDA.
Не стоит также устанавливать CUDA Toolkit, GPU Computing SDK
разных версий. Они могут оказаться несовместимы друг с другом.
стр. 3
(С) Павлий В.А., кафедра КСМ, ДонНТУ, 2014
После этого в Visual Studio потребуется указать пути к директориям
CUDA Toolkit, в которых хранятся основные заголовочные файлы,
исполняемые файлы и библиотеки. Для этого следует открыть окно с
настройками параметров (“Сервис” – “Параметры”), а во вкладке “Проекты и
решения” выбрать пункт “Каталоги VC++”. В качестве платформы по
умолчанию следует выбрать “Win32” или “Win64” в зависимости от
разрядности ОС, в поле “Показать каталоги для” выбрать “Исполняемые
файлы”, как показано на рис. 1.
Рис. 1. – Настройка путей к CUDA Toolkit
Далее по нажатию кнопки
нужно создать новую строку и вписать
путь к папке, в которой хранятся исполняемые файлы CUDA Toolkit. Как
правило, эти файлы находятся в папке bin, которая, в свою очередь, была
создана при установке CUDA Toolkit. Таким образом, полный путь, который
следует указать в настройках Visual Studio, выглядит так:
[C:\CUDA\TOOLKIT\bin].
Далее следует проверить существование указанного пути, нажав
кнопку
. Если введенный путь некорректен, появится окно с сообщением
об ошибке; если же все пути из указанного списка исполняемых файлов
существуют, ничего не произойдет. Не стоит пренебрегать этой
проверкой: можно быть полностью уверенным, что путь указан корректно
(хотя на самом деле это не так) и потратить много времени в поисках ошибок
компиляции или отсутствующих библиотек в будущем.
Аналогично необходимо указать пути к заголовочным файлам и
библиотекам CUDA Toolkit. При этом в поле “Показать каталоги для”
следует выбирать “Включаемые файлы” и “Файлы библиотек”. Все
заголовочные файлы библиотеки CUDA Toolkit находятся в папке include,
все библиотеки – в папке lib соответственно.
После указания путей к заголовочным файлам и библиотекам не
забывайте проверять их корректность, каждый раз нажимая на кнопку
.
стр. 4
(С) Павлий В.А., кафедра КСМ, ДонНТУ, 2014
Часть 2. Создание и настройка первого проекта для CUDA
Материал, описываемый в данной части, показывает, как создать
проект, настроить интеграцию установленного ранее программного
обеспечения, скомпилировать и запустить первое приложение для работы с
CUDA. Обратите внимание – при создании нового проекта настройка должна
выполняться каждый раз заново, поэтому, скорей всего, Вам придется
возвращаться к данной части повторно.
Для начала создадим новое консольное приложение Win32 С++. В
настройках создания отметим опцию “Пустой проект”. При создании
проекта не используйте папку для проектов по умолчанию, а старайтесь
использовать короткие пути без русских букв. Автор этих методических
указаний потратил несколько дней, пытаясь понять, откуда берутся ошибки
даже при компиляции пустого проекта CUDA. Как оказалось впоследствии,
проект нужно было перенести в папку с короткими путями. Наиболее
оптимальный вариант – создать папку
[С:\CUDA\PROJECTS]
и создавать все проекты в ней. Попутно отметим, что данное правило
создания проектов актуально для версии CUDA ToolKit версии 2.3.
Возможно в последующих версиях (а сейчас уже вышла 6.5) данный
недостаток был исправлен.
Рис. 2. – Создание нового проекта CUDA (1 шаг)
стр. 5
(С) Павлий В.А., кафедра КСМ, ДонНТУ, 2014
Рис. 3. – Создание нового проекта CUDA (2 шаг)
После создания нового проекта Вам следует проверить, добавились ли
правила сборки в Visual Studio. В последних версиях CUDA Toolkit это
выполняется автоматически. Правила сборки могут не добавляться в старых
версиях CUDA Toolkit. Кроме того, правила сборки не будут добавлены, если
Вы, например, установите сначала CUDA Toolkit, а только потом Visual
Studio – в этом случае их просто еще некуда добавлять.
Проверить добавились ли правила сборки можно через контекстное
меню проекта.
Рис. 4. – Вызов диалога Пользовательские правила построения
Рис. 5. – Диалог “Пользовательские правила построения”
стр. 6
(С) Павлий В.А., кафедра КСМ, ДонНТУ, 2014
В диалоге “Пользовательские правила построения” в названиях правил
ищите строку “CUDA”. Таких правил может быть несколько, а их полные
названия могут отличаться в зависимости от версии CUDA Toolkit. Автору
встречались варианты “CUDA C/C++”, “CUDA Driver API”, “CUDA Runtime
API” и т.д.
Если подобных правил в указанном диалоге нет (как получилось,
например, на рис. 5), Вам потребуется добавить их самостоятельно. Для
этого в папке с установленным пакетом CUDA Toolkit поищите файл с
названием [Cuda.Rules]. Если такого файла нет, попробуйте поискать его в
папке с установленным пакетом GPU Computing SDK (в старых версиях файл
Cuda.Rules может находиться в нем). Таких файлов Вы можете найти
несколько, в разных поддиректориях. Добавьте все найденные правила
вручную при помощи кнопки “Найти существующий”. В результате
диалоговое окно примет вид, показанный на рис. 6.
Рис. 6. – Диалог “Пользовательские правила построения” с добавленным
правилом сборки для CUDA-программ
Для того чтобы задействовать правила сборки в Вашем проекте,
необходимо отметить флажок слева от названия правила и нажать кнопку
“ОК”. Если же у Вас имеется несколько правил (в старших версиях CUDA
Toolkit, например, есть разделение на CUDA Runtime API и CUDA Driver
API), следует выбирать CUDA Runtime API. Именно CUDA Runtime API
предоставляет интерфейс для более простых программ CUDA, в то время как
CUDA Driver API более сложен в освоении, но вместе с тем дает доступ к
низкоуровневому программированию для CUDA. Для начинающих он не
нужен, и в данном цикле лабораторных работ не рассматривается.
На следующем этапе нужно создать новый файл с исходным кодом в
проекте. Для этого следует воспользоваться пунктом “Создать элемент” из
контекстного меню проекта (см. рис. 7). Далее нужно выбрать файл типа
С++. Имя файла может быть любым, но расширение файла обязательно
стр. 7
(С) Павлий В.А., кафедра КСМ, ДонНТУ, 2014
следует задавать вручную, как показано на рис. 8. Традиционно файлы
исходного кода CUDA имеют расширение *.cu. Если Вы не зададите
расширение самостоятельно, указанный файл будет обычным *.cpp файлом,
и добавленные ранее правила для него станут неприменимы. Из рисунка 6
можно понять, что именно по расширению файла Visual Studio определяет,
какие правила для него нужно задействовать и как его компилировать.
Рис. 7. – Создание нового файла с исходным кодом (шаг 1)
Рис. 8. – Создание нового файла с исходным кодом (шаг 2)
После создания файла следует убедиться в том, что к нему
применились правила CUDA. Для этого нужно открыть свойства файла (не
проекта!) и убедиться в том, что в поле “Инструмент” вкладки “Общие”
задействуется именно подключенные ранее правила сборки CUDA (см. рис. 9
– рис. 10). Если по каким-либо причинам в поле инструмент окажется другой
инструмент – можно переназначить инструмент вручную, выбрав его из
списка.
стр. 8
(С) Павлий В.А., кафедра КСМ, ДонНТУ, 2014
Рис. 9. – Проверка соответствия исходного файла правилам CUDA (шаг 1)
Рис. 10. – Проверка соответствия исходного файла правилам CUDA (шаг 1)
Далее следует настроить пути для поиска средой Visual Studio
компилятора CUDA программ, библиотек CUDA, заголовочных файлов и
других исполняемых файлов (которые входят в состав CUDA ToolKit).
Понадобится выполнить несколько настроек в свойствах проекта:
- во-первых, нужно указать месторасположение библиотек CUDA во
вкладке “Компоновщик – Общие – Дополнительные каталоги библиотек”,
как показано на рис. 11. Здесь следует указать путь к папке, в которой
хранятся библиотеки CUDA (файлы *.lib). Эта папка входит в состав CUDA
ToolKit. Если таких папок в Вашей версии CUDA ToolKit несколько, то,
нужно выбрать ту из них, которая соответствует типу Вашей операционной
системы и выбранной версии CUDA API. Например, если файлы *.lib
находятся в папке “runtime/lib/win32/*.lib” и у Вас 32 разрядная версия
Windows, то выбирать нужно именно эту папку (помня о том, что в цикле
лабораторных работ используется Runtime CUDA API).
стр. 9
(С) Павлий В.А., кафедра КСМ, ДонНТУ, 2014
- во-вторых, следует указать библиотеку “cudart.lib” на вкладке
“Компоновщик – Общие – Ввод”. Здесь можно ограничиться одним именем
файла, без указания пути (см. рис. 12).
Рис. 11. – Подключение библиотек CUDA
Рис. 12. – Подключение cudart.lib
Наконец, для студентов, у которых нет реальной видеокарты от
NVidia, поддерживающей CUDA, необходимо включить режим эмуляции
CUDA устройства. Обратите внимание на следующий любопытный факт:
стр. 10
(С) Павлий В.А., кафедра КСМ, ДонНТУ, 2014
если режим эмуляции не включен, то программа компилируется и даже
работает, только участки кода, которые должны исполняться на устройстве
CUDA, просто игнорируются, хотя по идее должна возникать ошибка
компиляции. Поэтому будьте внимательны и всегда включайте режим
эмуляции, иначе результат выполнения Вашей программы будет не таким,
как Вы ожидаете. Для того чтобы включить режим эмуляции в свойствах
проекта зайдите во вкладку “CUDA Build Rule v2.3.0 – General – Emulation
Mode” и выберите “Да” напротив соответствующего свойства (см. рис. 13).
Рис. 13. – Включение режима эмуляции (для CUDA ToolKit v2.3.0)
Теперь стоит проверить, как компилируется простейшее приложение
CUDA. Откройте созданный ранее файл исходного кода и введите в него
следующий фрагмент:
#include <stdio.h>
__global__ void add(int a, int b, int *c)
{
*c = a + b;
}
int main(void)
{
int c = 0; int *dev_c;
cudaMalloc ((void**)&dev_c, sizeof(int));
add<<<1,1>>>(2, -1, dev_c);
cudaMemcpy (&c, dev_c, sizeof(int), cudaMemcpyDeviceToHost);
printf("%d", c);
system("pause");
return 0;
}
стр. 11
(С) Павлий В.А., кафедра КСМ, ДонНТУ, 2014
Нетрудно догадаться (несмотря на местами незнакомый синтаксис),
что делает этот фрагмент кода: складывает 2 числа, -1 и 2, и выводит
результат на экран. Но происходит это уже на CUDA устройстве. Поэтому
если в результате Вы увидите 1, значит, Вы все сделали правильно. Если в
результате будет 0, то, скорей всего, Вы забыли включить режим эмуляции.
Могут также возникнуть и ошибки компиляции. В этом случае попробуйте
скомпилировать такой код:
int main(void)
{
return 0;
}
Если и в этом случае будут возникать ошибки компиляции, то можно
проверить следующее:
- если возникают ошибки вида “newline в константе”, то эта ошибка,
скорей всего, связана с тем, что в пути к проекту или в пути к библиотекам
имеются русские буквы;
- если возникают ошибки вида “неразрешенная ссылка” – проверьте
еще раз правильность указания путей ко всем библиотекам.
- наконец, при компиляции проектов Ваш антивирус может “ругаться”.
Просто добавьте компилятор nvcc.exe в список разрешенных приложений.
Уж в нем-то вируса точно нет, при условии, что Вы скачали CUDA Toolkit с
официального сайта NVidia.
Часть 3. Изучение синтаксиса языка CUDA C
После создания первого проекта CUDA следует более глубоко
познакомиться с синтаксисом языка CUDA. Данный материал выходит за
рамки практической части, поэтому его лучше изучать по теоретическому
материалу, прилагаемому к данной работе, конспекту лекций или по
дополнительным источникам. Одним из лучших источников сегодня
является работа авторов Сандерс Дж., Кендрот Э. “Технология CUDA в
примерах”. Здесь отметим лишь, что язык CUDA С очень сильно похож на
обычный С, поэтому многие элементы синтаксиса окажутся Вам знакомы.
Исключение составят лишь дополнительные функции и конструкции языка.
Часть 4. Задание
После ознакомления с синтаксисом языка, следует разработать
программу на языке CUDA С в соответствии с вариантами заданий к
лабораторной работе, приведенным в таблице 1. Все задания подобраны
таким образом, чтобы ощущался эффект от использования CUDA
технологии, в первую очередь, это, конечно же, время выполнения
программы. Но и для студентов, не имеющих реального оборудования,
выполнение программы не должно превращаться в мучительное ожидание. В
стр. 12
(С) Павлий В.А., кафедра КСМ, ДонНТУ, 2014
результате объем вычислительной работы выбирался так, чтобы достигалась
“золотая середина”.
Во всех заданиях требуется создать матрицу (вектор) или несколько
матриц (векторов) одинаковой размерности, указанной в таблице 1,
заполнить их считанными из текстового файла значениями. Текстовые файлы
следует предварительно подготовить, заполнив их случайными числами.
Затем реализовать задание, используя обработку данных на CUDA. В конце
вывести результаты вычислений опять в текстовый файл.
Интерфейс программы – консольное приложение. В самом начале
программа спрашивает имя входного и выходного файлов. Затем, после
выполнения всех вычислений, печатает общее время работы (в секундах) на
экране в виде дробного числа.
Для измерения времени работы кода см. функции GetTickCount(),
clock(). Общий принцип таков: засекаем время до начала вычислений,
засекаем после, отнимаем от второго первое, печатаем результат.
Содержание отчета:
- титульный лист;
- задание;
- код программы;
- экранная форма разработанного приложения;
- выводы.
Варианты заданий
Таблица 1. Описание заданий
№
1
2
3
4
5
6
7
8
9
Размерность
массива
или
матрицы
217x217
216x216
215x215
217x217
211x211
216x216
215x215
217x217
216x216
10 215x215
11
12
234
233
Тип
данны
х
цел.
вещ.
цел.
вещ.
цел.
вещ.
цел.
вещ.
цел.
Описание задания
Вычислить матрицу C = ½*A+B
Вычислить матрицу C = (A+B)*5+8
Вычислить матрицу C = (B–A)* ½–8
Вычислить матрицу С = A*5 – B*8 + 3
Вычислить произведение матриц C = A*B
Вычислить транспонированную матрицу C = AT
Проверить, является ли матрица A диагональной
Проверить, является ли матрица A единичной
Проверить, является ли матрица A нулевой
Проверить, что все числа в матрице меньше числа k,
вещ.
которое задает пользователь
цел. Вычислить одномерный массив C = (A–B)*4+5
вещ. Вычислить одномерный массив C = (A+B)*6–10
стр. 13
(С) Павлий В.А., кафедра КСМ, ДонНТУ, 2014
13
14
15
16
232
231
230
234
цел.
вещ.
цел.
вещ.
17
233
цел.
18
19
232
231
вещ.
цел.
20
230
вещ.
21
22
23
24
25
26
27
28
29
216x216
215x215
214x214
216x216
210x210
215x215
214x214
216x216
215x215
вещ.
цел.
вещ.
цел.
вещ.
цел.
вещ.
цел.
вещ.
30 214x214
цел.
31
32
33
34
35
36
233
232
231
230
229
233
вещ.
цел.
вещ.
цел.
вещ.
цел.
37
232
вещ.
38
39
231
230
цел.
вещ.
40
229
цел.
Вычислить одномерный массив C = (B–A)*½–8
Вычислить одномерный массив C = A*3–B+3
Вычислить одномерный массив C = B+3*A–8
Вычислить отраженный относительно середины массив C
Поменять в одномерном массиве элементы, находящиеся
на четных и нечетных местах
Проверить, является ли одномерный массив единичным
Проверить, является ли одномерный массив нулевым
Проверить, что все числа в одномерном векторе меньше
числа k, которое задает пользователь
Вычислить матрицу C = ½*A+B
Вычислить матрицу C = (A+B)*5+8
Вычислить матрицу C = (B–A)* ½–8
Вычислить матрицу С = A*5 – B*8 + 3
Вычислить произведение матриц C = A*B
Вычислить транспонированную матрицу C = AT
Проверить, является ли матрица A диагональной
Проверить, является ли матрица A единичной
Проверить, является ли матрица A нулевой
Проверить, что все числа в матрице меньше числа k,
которое задает пользователь
Вычислить одномерный массив C = (A–B)*4+5
Вычислить одномерный массив C = (A+B)*6–10
Вычислить одномерный массив C = (B–A)*½–8
Вычислить одномерный массив C = A*3–B+3
Вычислить одномерный массив C = B+3*A–8
Вычислить отраженный относительно середины массив C
Поменять в одномерном массиве элементы, находящиеся
на четных и нечетных местах
Проверить, является ли одномерный массив единичным
Проверить, является ли одномерный массив нулевым
Проверить, что все числа в одномерном векторе меньше
числа k, которое задает пользователь
Скачать