- •ВВЕДЕНИЕ
- •1. ПРЕДПОСЫЛКИ ВОЗНИКНОВЕНИЯ ЯЗЫКА OPENCL
- •2. ДИЗАЙН OPENCL
- •2.1. Модель платформы
- •2.2. Модель вычислений
- •2.3. Модель памяти
- •2.4. Модель программирования
- •3. АППАРАТНЫЕ СРЕДСТВА, ПОДДЕРЖИВАЮЩИЕ ПАРАЛЛЕЛЬНЫЕ ВЫЧИСЛЕНИЯ
- •4. ЛАБОРАТОРНЫЕ РАБОТЫ
- •4.1. Поток проектирования при работе с языком OpenCL
- •4.1.1. Задание
- •4.1.2. Программное и аппаратное обеспечение
- •4.1.3. Последовательность выполнения работы
- •4.1.4. Заключение по практическому эксперименту
- •4.1.5. Содержание отчета
- •4.2. Создание аппаратно-программной системы с ОС Linux. Подключение к Ethernet. Работа с Web-сервером
- •4.2.1. Задание
- •4.2.2. Последовательность выполнения работы
- •4.2.3. Содержание отчета
- •4.3. Оптимизация умножения матриц в OpenCL
- •4.3.1. Базовый алгоритм умножения матриц
- •4.3.2. Использование локальной памяти
- •4.3.3. Увеличение числа одновременно исполняемых рабочих элементов
- •4.3.4. Содержание отчета
- •СПИСОК ЛИТЕРАТУРЫ
- •ИНТЕРНЕТ-РЕСУРСЫ
- •ПРИЛОЖЕНИЯ
- •П1. Код хост-программы для сложения двух векторов
- •П2. Исходный код хост-программы для умножения двух матриц
4.ЛАБОРАТОРНЫЕ РАБОТЫ
4.1.Поток проектирования при работе с языком OpenCL
Цель работы – ознакомить учащихся с полным потоком проектирования на языке OpenCL в САПР фирмы Altera для SOPC. При выполнении работы происходит ознакомление как с компилятором для языка, так и с некоторыми командами языка.
Необходимость работ (типа содержания первой лабораторной работы) возникает при требованиях заказчика реализовать аппаратно-программную систему на базе SOPC фирмы Altera. Большинство программных приложений опираются в своей работе на стандартные операционные системы (обычно это та илиинаяразновидностьLinux). Поэтомукроме SOPCнаплатедолжныбыть предусмотренысредствадляразвертыванияОС Linux.Linuxудобнозагружать с MicroSD карты. Набор требуемого для этого оборудования весьма традиционен: процессор (наибольшее распространение для SOPC фирмы Altera получили процессоры типа ARM), картридж для SD карты, загрузочная постоянная память (как правило, требуется не более нескольких сотен байт), оперативная память (обычно динамическая память порядка 2…4 Мбайт), контроллер прямого доступа к памяти. Для связи ОС с оператором должна обеспечиваться связь типа точка–точка. Тип контроллера связан с типом связи. Терминалы, как правило, подсоединяются через разъемы JTAG.
4.1.1. Задание
Разработать и отладить программу на языке OpenCL, выполняющую задачу сложения двух векторов A и B, содержимое которых формируется с помощьюпрограммногодатчикапсевдослучайных,равномернораспределенных чисел в диапазоне от −10 до 10. Размерность слагаемых и результата соответствует 1 млн. Проект необходимо разместить в SoPC платы DE1-SoC.
4.1.2. Программное и аппаратное обеспечение
При выполнении данной работы необходимо использовать следующее программное и аппаратное обеспечение:
−ОС Windows 10 64-bit, ОС Linux;
−САПР Quartus II Prime + SoC EDS v17.0.2;
−Intel FPGA SDK for OpenCL v17.0.2;
−BSP (Board Support Package) for Altera SDK OpenCL 16.0;
−Win32DiskImager v1.0;
11
−PuTTY 64-bit;
−плата DE1-SoC ревизии D фирмы Terasic.
Рис. 4.1. Структурная схема проектируемой системы
Структурная схема проектируемой системы приведена на рис. 4.1. Наличие в SoPC FPGA достаточно большого числа вентилей позволяет воспользоваться возможностями параллельного программирования языка (конструкция kernel) для мультиплицирования операций сложения векторов.
4.1.3.Последовательность выполнения работы
1.Запись образа карты памяти и запуск тестовых примеров.
1.1.В материалах работы найти архив DE1_SoC_OpenCL_BSP_16.0_ V1.1.zip. (специальныйBSPдляплатыDE1-SoCдляAlteraOpenCL SDKможно скачать с интернет-ресурса).
1.2.Разархивироватьданный архив (сначала в произвольное место). В состав архива входит образ MicroSD карты памяти, некоторые тестовые примеры, проекты, драйверы и т. д.
1.3.Распаковать файл linux_sd_card_image.zip, содержащий образ карты памяти с ОС Linux. Записать его на карту памяти (необходима MicroSD карта емкостью минимум 4 Гбайт) с помощью программы Win32DiskImager (также можно использовать команду dd в ОС Linux).
1.4.Отрегулировать переключатель MSEL[4..0] на плате DE1-SoC, установив в положение 01010.
12
1.5.Настроить соединение с помощью утилиты Putty (115200/8/1, Parity: None, Flow Control: None), подать питание на плату.
1.6.Дождаться загрузки Linux. В ответ на приглашение авторизации ввести root. Содержимое домашнего каталога выглядит следующим образом:
root@socfpga:~# ls
README hello_world opencl_arm32_rte vector_add board_test init_opencl.sh swapper
Образ карты памяти уже содержит предустановленную среду исполнения OpenCL в папке opencl_arm32_rte, а также некоторые тестовые примеры.
1.7.Выполнить скрипт для настройки переменных окружения:
root@socfpga:~# source ./init_opencl.sh
Данную операцию необходимо выполнять каждый раз после загрузки платы. Сам скрипт выглядит следующим образом:
root@socfpga:~# cat init_opencl.sh
export ALTERAOCLSDKROOT=/home/root/opencl_arm32_rte root@socfpga:~# cat init_opencl.sh
export ALTERAOCLSDKROOT=/home/root/opencl_arm32_rte
export AOCL_BOARD_PACKAGE_ROOT=$ALTERAOCLSDKROOT/board/c5soc export PATH=$ALTERAOCLSDKROOT/bin:$PATH
export LD_LIBRARY_PATH=$ALTERAOCLSDKROOT/host/arm32/ lib:$LD_LIBRARY_PATH
insmod $AOCL_BOARD_PACKAGE_ROOT/driver/aclsoc_drv.ko
Скрипт устанавливает переменные окружения, необходимые для работы OpenCL, а также загружает в ядро Linux соответствующий драйвер.
1.8.Запустить предлагаемый тестовый пример:
root@socfpga:~# cd hello_world/ root@socfpga:~/hello_world# aocl program /dev/acl0
hello_world.aocx
aocl program: Running reprogram from /home/root/opencl_arm32_rte/board/c5soc/arm32/bin
Reprogramming was successful! root@socfpga:~/hello_world# ./hello_world
|
|
|
|
|
|
|
|
|
|
|
Querying platform for info: |
|
|
|
|
|
|||
|
CL_PLATFORM_NAME |
= Altera |
SDK for OpenCL |
||||||
|
CL_PLATFORM_VENDOR |
= Altera |
Corporation |
|
|
||||
|
CL_PLATFORM_VERSIO |
= OpenCL |
1.0 Altera |
SDK |
|||||
for |
OpenCL, Version 16.0 |
|
|
|
|
|
|
|
|
|
Querying device for |
info: |
|
|
|
|
|
|
|
|
CL_DEVICE_NAME = de1soc_ |
sharedonlyCycloneV |
SoC |
DevelopmentKit |
|||||
|
CL_DEVICE_VENDOR |
= |
Altera Corporation |
||||||
|
CL_DEVICE_VENDOR_ID |
= |
4466 |
|
|
|
|||
|
CL_DEVICE_VERSION |
= |
OpenCL 1.0 Altera |
|
|||||
SDK |
for OpenCL, Version 16.0 |
|
|
|
|
|
|
13
|
|
|
|
|
|
|
|
======================== |
|
|
|
|
|
|
|
CL_DRIVER_VERSION |
|
|
= 16.0 |
|
|
||
CL_DEVICE_ADDRESS_BITS |
= 64 |
|
|
|
|||
CL_DEVICE_AVAILABLE |
= true |
|
|
||||
CL_DEVICE_ENDIAN_LITTLE |
= true |
|
|
||||
CL_DEVICE_GLOBAL_MEM_CACHE_SIZE |
= 32768 |
|
|
||||
CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE |
= 0 |
|
|
|
|
||
CL_DEVICE_GLOBAL_MEM_SIZE |
= |
536870912 |
|||||
CL_DEVICE_IMAGE_SUPPORT |
= true |
|
|||||
CL_DEVICE_LOCAL_MEM_SIZE |
= 16384 |
|
|
||||
CL_DEVICE_MAX_CLOCK_FREQUENCY |
= 1000 |
|
|
||||
CL_DEVICE_MAX_COMPUTE_UNITS |
= 1 |
|
|
|
|
||
CL_DEVICE_MAX_CONSTANT_ARGS |
= 8 |
|
|
|
|
||
CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE |
= |
134217728 |
|||||
CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS |
= 3 |
|
|
|
|
||
CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS |
= |
8192 |
|
|
|||
CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE |
= 1024 |
|
|
||||
CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR |
= 4 |
|
|
|
|
||
CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT |
= 2 |
|
|
|
|
||
CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT |
= 1 |
|
|
|
|
||
CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG |
= 1 |
|
|
|
|
||
|
|
|
|
|
|
|
|
CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT |
= 1 |
|
|
|
|
||
CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE |
= 0 |
|
|
|
|
||
Command queue out of order? |
= |
false |
|
||||
Command queue profiling enabled? |
= true |
|
|
||||
======================== |
|
|
|
|
|
|
|
Using AOCX: hello_world.aocx |
|
|
|
|
|
|
|
Reprogramming device with handle 1 |
|
|
|
|
|
Kernel initialization is complete.
Launching the kernel...
Thread #2: Hello from Altera's OpenCL Compiler!
Kernel execution is complete.
С помощью команды aocl program загрузить OpenCL-ядро, которое будет выполняться на FPGA. Эти ядра имеют расширение .aocx (Altera Offline Compiler Executable) и представляют собой исполняемые файлы.
В данном случае задачей ядра является простой вывод сообщения. Исходный код выглядит следующим образом:
__kernel void hello_world(int thread_id_from_which_to_print_message){
// получить индекс потока
unsigned thread_id = get_global_id(0);
// если полученный индекс совпадает с аргументом, переданным ядру, то вывести сообщение
if(thread_id == thread_id_from_which_to_print_message){ printf("Thread #%u: Hello from Altera's OpenCL Compiler!\n",
thread_id);}
}
14
1.9.После загрузки ядра необходимо запустить бинарный исполняемый файл, который представляет собой хост-программу и выполняется на ядре ARM. Хост-программа в общем случае отвечает за организацию вычислений, подачу исходных и получение выходных данных, организацию интерфейса взаимодействия с аппаратурой [9]. В данном случае дополнительно осуществляется вывод информации о среде исполнения OpenCL, а также установка аргумента для ядра:
static const int thread_id_to_output = 2;
status = clSetKernelArg(kernel, 0, sizeof(cl_int), (void*)&thread_id_to_output);
Ядрувкачествеаргументапередается число 2. Поток с этим номеромдолжен вывести сообщение «Hello …». Целиком код хост-программы можно по-
смотреть в файле examples/hello_world/host/src.
2. Компиляция программ (с использованием компилятора AOC).
2.1.Создадим программу OpenCL для сложения двух векторов из N uint (32-битных) чисел. Для этого понадобится ядро и хост-программа. Код ядра приведен ниже.
__kernel void vector_add(__global const uint *restrict x, __global const uint *restrict y,__global uint *restrict z)
{
//получить индекс work-item int index = get_global_id(0);
//сложить соответствующие элементы векторов z[index] = x[index] + y[index];}
Можно обратить внимание, что в коде не используются циклы. Так как индекс work-item, получаемый функцией get_global_id(0), лежит в диапазоне [0; N) и, таким образом, представляет собой счетчик цикла.
2.2.Код ядра следует поместить в файл %ALTERAOCLSDKROOT%
\board\de1soc\examples\hello_world\device\vector_add.cl. Для его сборки необ-
ходимо в командной строке Windows перейти в директорию
%ALTERAOCLSDKROOT%\board\de1soc\examples\hello_world и выполнить следующую команду:
aoc device/vector_add.cl -o bin/vector_add.aocx --board de1soc_sharedonly --profile –v
Эта команда запускает компиляцию ядра из его исходного кода и сборку прошивки FPGA. Если компилятор попросит удалить папку bin/vector_add,
15
необходимо это сделать и выполнить команду заново. Два последних ключа являются необязательными. Первый ключ добавляет в прошивкусчетчики для профилирования, а второй включает вывод информационных сообщений о процессе компиляции. Эти сообщения представлены ниже.
aoc: Environment checks are completed successfully.
========================
You are now compiling the full flow!!
aoc: Selected target board de1-soc_sharedonly aoc: Running OpenCL parser....
aoc: OpenCL parser completed successfully. aoc: Compiling....
aoc: Linking with IP library ...
========================
Checking if memory usage is larger than 100%
aoc: First stage compilation completed successfully. aoc: Hardware generation completed successfully.
========================
2.3.Результат компиляции находится в папке bin в файле vector_add.aocx. Код хост-программы приведен в приложении 1. Этот код необходимо по-
местить в файл %ALTERAOCLSDKROOT%\board\de1soc\examples\\ hello_world\host\src\main.cpp.
2.4.Для сборки хост-программы в SoC EDS необходимо перейти в дирек-
торию ALTERAOCLSDKROOT%\board\de1soc\examples\hello_world и выпол-
нить командуmake. Результат сборки– бинарный файл vector_add. Файлы vector_add и vector_add.aocx нужно поместить на ext4-раздел карты памяти,
например, в папку /home/root/va.
3. Запуск и исследование работы программ.
3.1.Запустить плату. Выполнить скрипт для установки переменных окружения:
root@socfpga:~# source ./init_opencl.sh
Просмотреть содержимое исполняемого файла ядра в удобном формате:
root@socfpga:~# cd va
root@socfpga:~/va# readelf -a vector_add.aocx
3.2.Загрузитьядро,установитьатрибутисполнениядляфайлапрограммы
изапустить ее:
root@socfpga:~/va# aocl program /dev/acl0 vector_add.aocx root@socfpga:~/va# chmod +x vector_add root@socfpga:~/va#./vector_add
Результат выполнения программы должен быть таким:
16
Initializing OpenCL
Platform: Altera SDK for OpenCL Using 1 device(s)
de1soc_sharedonlyCyclone V SoC Development Kit Using AOCX: vector_add.aocx
Reprogramming device with handle 1 Launching for device 0 (1000000 elements) Time: 162.767 ms
Kernel time (device 0): 6.880 ms Verification: PASS
Как видно, два вектора из 1 млн элементов суммированы за ~7 мс. На одно сложение, таким образом, затрачивается ~7 нс.
Содержимое папки:
|
|
|
|
|
|
|
|
|
|
|
|
|
root@socfpga:~/va# ls -l |
|
|
|
|
|
|
|
|
||
|
total 2536 |
|
|
|
|
|
|
|
|
|
|
|
-rw-r--r-- |
1 |
root root |
170 |
Aug 30 |
03:42 profile.mon |
|
|
|||
|
-rwxr-xr-x 1 |
root root |
42296 |
Dec |
14 |
2018 |
vector_add |
|
|
|
|
|
-rwxr-xr-x 1 |
root root 2545060 |
Dec |
14 |
2018 |
vector_add.aocx |
|
3.3.Файл с отчетом об исполнении программы profile.mon скопировать на компьютер и просмотреть (рис. 4.2):
aocl report bin\vector_add.aocx profile.mon
Рис. 4.2. Отчет об исполнении программы
17