Упрощение параллельных вычислений на платах Raspberry Pi 4B + IoT

Сборка и запуск параллельного кода на C ++ 17, реализованного с использованием спецификации CL / SYCL-модели Khronos, на платах Raspberry Pi IoT.

Наши цели…

В этом проекте представлены полезные рекомендации, советы и руководства по созданию современного параллельного кода на C ++ 17 / 2x0, реализованному с использованием модели программирования CL / SYCL, и его запуску на платах Raspberry Pi 4B IoT следующего поколения на основе инновационных ARM Cortex-A72, четырехъядерные, 64-битные процессоры RISC-V.

Аудитория читателей узнает о настройке платы Raspberry 4B IoT прямо из коробки и использовании ее для параллельных вычислений, доставки параллельного кода на C ++ 17, с помощью Khronos CL / triSYCL и Акселя Алпая. Дистрибутивы проекта hipSYCL с открытым исходным кодом, установка и настройка GNU Compiler Collection (GCC) и LLVM / Clang-9.xx Arm / Aarch64-toolchains, для создания исполняемых файлов параллельного кода и запуска его в ОС Raspbian Buster 10.6.

Обзор плат Raspberry PI 4B + IoT

Новое поколение инновационных плат Raspberry Pi 4B + IoT, основанных на мощных многоядерных симметричных 64-битных RISC-V процессорах ARM, обеспечивает непревзойденную производительность и, следовательно, максимальную производительность параллельных вычислений. Использование новейших плат Raspberry Pi позволяет значительно повысить фактическое ускорение вычислительных процессов на периферии, таких как сбор и предварительная обработка данных в реальном времени, перед их доставкой в ​​центр обработки данных для обработки на экзафлопсах. Параллельное выполнение этих процессов значительно повышает эффективность этих облачных решений, обслуживая миллиарды клиентских запросов или обеспечивая аналитику данных и другие выводы.

Прежде чем мы обсудим создание и запуск параллельного кода на C ++ 17, разработанного с использованием спецификации модели гетерогенного программирования CL / SYCL для плат Raspberry Pi с архитектурой Arm / Aarch64, давайте потратим немного времени и сделаем короткое Взглянем на следующее поколение плат Raspberry Pi 4B + и его технические характеристики:

Платы Raspberry Pi 4B + IoT производятся на основе инновационных чипов Broadcom BCM2711B0 (SoC), оснащенных новейшими четырехъядерными процессорами ARM Cortex-A72 с тактовой частотой 1,5 ГГц, 64-разрядными RISC-V, обеспечивающими максимальную производительность и масштабируемость при одновременном использовании для параллельные вычисления на периферии.

Raspberry Pi известен своими «надежными» и «быстрыми» крошечными нанокомпьютерами, предназначенными для интеллектуального анализа данных и параллельных вычислений. Принципиально новые аппаратные архитектурные особенности многоядерных симметричных 64-разрядных процессоров RISC-V ARM, такие как DSP, SIMD, VFPv4 и поддержка аппаратной виртуализации, могут значительно улучшить производительность, ускорить ускорение и масштабируемость IoT-кластеры, массово обрабатывающие данные, на границе.

В частности, одним из наиболее важных преимуществ новейших плат Raspberry Pi 4B + является низкопрофильная память LPDDR4 с объемом оперативной памяти 2, 4 или 8 ГиБ на выбор, работающая на частоте 3200 МГц и обеспечивающая обычно большую пропускную способность для транзакций памяти, что положительно влияет на производительность. производительность параллельных вычислений в целом. Платы с установленной оперативной памятью 4 ГиБ и выше настоятельно рекомендуются для интеллектуального анализа данных и параллельных вычислений. Кроме того, чипы SoC BCM2711B0 поставляются в комплекте с различными интегрированными устройствами и периферийными устройствами, такими как графические процессоры Broadcom VideoCore VI @ 500 МГц, адаптеры PCI-Ex Gigabit Ethernet и т. Д.

Для создания и запуска конкретного параллельного современного кода на C ++ 17, реализованного с использованием модели гетерогенного программирования CL / SYCL, первое, что нам действительно нужно, это IoT-плата Raspberry Pi 4B + с последней установленной и настроенной ОС Raspbian Buster 10.6. первое использование.

Вот краткий контрольный список требований к оборудованию и программному обеспечению:

Оборудование:

  • Raspberry Pi 4 Model B0, плата IoT 4 ГБ;
  • Карта Micro-SD 16 ГБ для ОС Raspbian и хранения данных;
  • Источник питания постоянного тока: 5,0 В / 2–3 А через разъем USB Type-C (минимум 3 А - для интеллектуального анализа данных и параллельных вычислений);

Программное обеспечение:

  • Raspbian Buster 10.6.0 Полная ОС;
  • Raspbian Imager 1.4;
  • MobaXterm 20.3 build 4396 или любой другой SSH-клиент;

Поскольку у нас есть плата Raspberry Pi 4B + IoT, теперь мы можем приступить к ее включению и настройке прямо из коробки.

Настройка платы Raspberry Pi 4B IoT

Прежде чем мы начнем, мы должны загрузить последний выпуск полного образа ОС Raspbian Buster 10.6.0 из официального репозитория Raspberry Pi. Чтобы установить образ ОС Raspbian на SD-карту, нам также необходимо загрузить и использовать приложение Raspbian Imager 1.4, доступное для различных платформ, таких как Windows, Linux или macOS:

Кроме того, мы также должны загрузить и установить приложение MobaXterm для удаленного подключения к плате Raspberry Pi по SSH- или FTP-протоколам:

Поскольку операционная система Raspbian Buster и приложение Imager были успешно загружены и установлены, мы будем использовать приложение Imager для следующих действий:

1. Сотрите SD-карту, по умолчанию отформатировав ее в файловую систему FAT32;

2. Распакуйте предустановленный образ ОС Raspbian Buster (* .img) на SD-карту;

Поскольку описанные выше шаги были выполнены, извлеките SD-карту из устройства чтения карт и вставьте ее в слот для SD-карты платы Raspberry Pi. Затем подключите кабели micro-HDMI и Ethernet. Наконец, подключите разъем кабеля питания постоянного тока и включите плату. Наконец, система загрузится с установленной на SD-карту ОС Raspbian Buster, предлагая выполнить несколько шагов после установки, чтобы настроить ее для первого использования.

Поскольку плата была включена, убедитесь, что все следующие шаги после установки были выполнены:

1. Откройте консоль bash и установите пароль «root»:

pi@raspberrypi4:~ $ sudo passwd root

2. Войдите в консоль Raspbian bash с правами «root»:

pi@raspberrypi4:~ $ sudo -s

3. Обновите базовую систему и прошивку Linux Raspbian, используя следующие команды:

root@raspberrypi4:~# sudo apt update
root@raspberrypi4:~# sudo apt full-upgrade
root@raspberrypi4:~# sudo rpi-update

4. Перезагрузите систему в первый раз:

root@raspberrypi4:~# sudo shutdown -r now

5. Установите последнюю версию загрузчика Raspbian и перезагрузите систему еще раз:

root@raspberrypi4:~# sudo rpi-eeprom-update -d -a
root@raspberrypi4:~# sudo shutdown -r now

6. Запустите инструмент настройки «raspi-config»:

root@raspberrypi4:~# sudo raspi-config

7. Выполните следующие шаги с помощью инструмента «raspi-config»:

* Обновите инструмент raspi-config:

* Отключите графический интерфейс рабочего стола Raspbian при загрузке:

Параметры системы ›› Загрузка / автоматический вход ›› Автоматический вход в консоль:

* Увеличьте размер корневого раздела ‘/’ на SD-карте:

После выполнения настройки после установки Raspbian, наконец, перезагрузите систему. После перезагрузки вам будет предложено войти в систему. Используйте имя пользователя «root» и пароль, ранее установленные для входа в консоль bash с привилегиями root.

Поскольку вы успешно вошли в систему, установите количество пакетов из репозиториев APT, используя следующую команду в bash-console:

root@raspberrypi4:~# sudo apt install -y net-tools openssh-server

Эти два пакета необходимы для настройки сетевого интерфейса Raspberry Pi или сервера OpenSSH для удаленного подключения к плате по протоколу SSH с помощью MobaXterm.

Настройте сетевой интерфейс платы «eth0», изменив файл / etc / network / interfaces, например:

auto eth0
iface eth0 inet static
address 192.168.87.100
netmask 255.255.255.0
broadcast 192.168.87.255
gateway 192.168.87.254
nameserver 192.168.87.254

Рядом с сетевым интерфейсом выполните базовую настройку OpenSSH-сервера, раскомментировав эти строки в файле / etc / ssh / sshd_config:

PermitRootLogin yes
StrictModes no
PasswordAuthentication yes
PermitEmptyPasswords yes

Это позволит войти в систему «root» в консоли bash по протоколу SSH без ввода пароля.

Наконец, попробуйте подключить плату по сети, используя приложение MobaXterm и открыв удаленную SSH-сессию с хостом с IP-адресом: 192.168.87.100. Вы также должны иметь возможность успешно войти в bash-console Raspbian с ранее установленными учетными данными:

Разработка параллельного кода на C ++ 17 с использованием CL / SYCL-модели

В 2020 году Khronos Group, Intel Corp. и другие поставщики анонсировали революционную новую гетерогенную платформу параллельных вычислений (XPU), дающую возможность переложить выполнение «тяжелых» рабочих нагрузок обработки данных на широко распространенное аппаратное ускорение (например, GPGPU или FPGA), кроме ЦП хоста. Концептуально разработка параллельного кода с использованием платформы XPU полностью основана на спецификации модели программирования Khronos CL / SYCL - уровне абстракции библиотеки OpenCL 2.0.

Вот небольшой пример, иллюстрирующий код на C ++ 17, реализованный с использованием уровня абстракции модели CL / SYCL:

#include <CL/sycl.hpp>
using namespace cl::sycl;
constexpr std::uint32_t N = 1000;
cl::sycl::queue q{};
q.submit([&](cl::sycl::handler &cgh) {
    cgh.parallel_for<class Kernel>(cl::sycl::range<1>{N}, \
       [=](cl::sycl::id<1> idx) {
           // Do some work in parallel
       });
});
q.wait();

Фрагмент кода C ++ 17, показанный выше, полностью основан на модели программирования CL / SYCL. Он создает экземпляр объекта cl :: sycl :: queue {} со списком инициализаторов параметров по умолчанию для отправки SYCL-ядер на выполнение в цель ускорения центрального процессора, используемую по умолчанию. Затем он вызывает метод cl :: sycl :: submit (…), имеющий единственный аргумент объекта cl :: sycl :: handler {} для доступа к методам, которые обеспечивают базовую функциональность ядра, основанную на множестве параллельных алгоритмов. , включая метод cl :: sycl :: handler :: parallel_for (…).

Следующий метод используется для реализации жесткого параллельного цикла, порожденного из работающего ядра. Каждая итерация этого цикла выполняется параллельно своим собственным потоком. Cl :: sycl :: handler :: parallel_for (…) принимает два основных аргумента объекта cl :: sycl :: range ‹› {} и конкретную лямбда-функцию, вызываемую во время каждой итерации цикла. Объект cl :: sycl :: range ‹› {} в основном определяет несколько выполняемых итераций параллельного цикла для каждого конкретного измерения в случае, когда несколько вложенных циклов сворачиваются при обработке многомерных данных.

В приведенном выше коде объект cl :: sycl :: range ‹1› (N) используется для планирования N-итераций параллельного цикла в одном измерении. Лямбда-функция метода parallel_for (…) принимает единственный аргумент другого объекта cl :: sycl :: id ‹› {}. Как и cl :: sycl :: range ‹› {}, этот объект реализует контейнер векторов, каждый элемент которого является значением индекса для каждого измерения и каждой итерации параллельного цикла соответственно. Следующий объект, переданный в качестве аргумента кода в области действия лямбда-функции, используется для получения определенных значений индекса. Тело лямбда-функции содержит код, который выполняет часть обработки данных параллельно.

После того, как определенное ядро ​​было отправлено в очередь и порождено для выполнения, следующий код вызывает метод cl :: sycl :: wait () без аргументов, чтобы установить синхронизацию барьера, гарантируя, что оно пока не будет выполнять никакого кода, пока порождаемое ядро ​​не завершит свою параллельную работу.

Модель гетерогенного программирования CL / SYCL очень эффективна и может использоваться для самых разных приложений.

Однако Intel Corp. и CodePlay Software Inc вскоре отказались от поддержки CL / SYCL для аппаратных архитектур, кроме x86_64. Это сделало невозможным создание параллельного кода C ++ с использованием определенных библиотек CL / SYCL, ориентированных на Arm / Aarch64 и другие архитектуры.

В настоящее время существует несколько проектов библиотек с открытым исходным кодом CL / SYCL, разработанных многими разработчиками и энтузиастами, обеспечивающих поддержку большего количества аппаратных архитектур, а не только x86_64.

С 2016 года Khronos Group, Inc. выпускает версии своего проекта с открытым исходным кодом библиотеки triSYCL (https://github.com/triSYCL/triSYCL), рекомендованного для использования в качестве испытательного стенда при оценке последней версии CL. / Спецификация уровня модели программирования SYCL и отправка отзывов в комитеты Khronos и ISO. Однако следующий дистрибутив библиотеки не является стабильным и может использоваться исключительно в демонстрационных целях, а не для создания кода CL / SYCL в производственной среде. Кроме того, дистрибутив библиотеки Khronos triSYCL полностью поддерживает кроссплатформенную компиляцию на машине разработки x86_64 с использованием кроссплатформенного инструментария GNU Arm / Aarch64, вместо того, чтобы создавать код изначально с помощью компиляторов LLVM / Clang на Raspberry. Пи.

В 2019 году Аксель Алпай из Гейдельбергского университета (Германия) внедрил новейшую библиотеку спецификации уровня модели программирования CL / SYCL, предназначенную для различных аппаратных архитектур, в том числе архитектуры Arm / Aarch64 Raspberry Pi, и внес наибольший вклад . стабильный выпуск дистрибутива библиотеки с открытым исходным кодом hipSYCL на GitHub ( https://github.com/illuhad/hipSYCL ).

Далее в этой истории мы обсудим установку и настройку кроссплатформенного GNU GCC / G ++ - 10.xx и «родных» наборов инструментов Arm / Aarch64 LLVM / Clang-9.xx, а также использование дистрибутивов библиотек triSYCL и hipSYCL для создание современного параллельного кода на C ++ 17, основанного на использовании обсуждаемых библиотек.

Создание CL / SYCL-кода на машине разработки Debian / Ubuntu (x86_64) и IoT-платах Raspberry Pi

Существует два основных метода построения CL / SYCL-кода в C ++ 17, представленных выше, с использованием кроссплатформенного инструментария GNU GCC / G ++ - 10.xx и машины разработки x86_64 на основе Debian / Ubuntu, или, «Изначально» на IoT-плате Raspberry Pi с установленным LLVM / Clang-9.xx для аппаратных архитектур Arm / Aarch64.

Использование первого метода позволяет создавать исходники кода на C ++ 17 / 2x0, реализованные с использованием библиотеки Khronos triSYCL и кроссплатформенного инструментария GNU Arm / Aarch64 на машине разработки x86_64 на основе Debian / Ubuntu, перед запуском на Raspberry Pi. .

Для развертывания машины разработки x86_64 требуется установка последней версии Debian Buster 10.6.0 или Ubuntu 20.04 LTS:

Чтобы иметь возможность использовать машину разработки на главном компьютере под управлением Microsoft Windows 10, для этой цели можно использовать любую из существующих сред виртуализации (например, Oracle VirtualBox или VMware Workstation):

Чтобы начать развертывание машины для разработки, все, что нам нужно было сделать, это настроить определенную среду виртуализации, создать виртуальную машину и запустить установку Debian или Ubuntu.

Поскольку виртуальная машина была создана и Debian / Ubuntu был успешно установлен, мы можем выполнить несколько шагов, включая установку и настройку кроссплатформенных компиляторов GNU GCC / G ++ - 10.xx, инструментов разработки и библиотеки Khronos triSYCL, требуется для создания кода, ориентированного на архитектуры Raspberry Pi Arm / Aarch64.

Перед установкой и настройкой набора инструментов компиляторов GCC / G ++ и библиотек времени выполнения убедитесь, что выполнены следующие предварительные шаги:

  • Обновите базовую систему Linux Debian / Ubuntu:
root@uarmhf64-dev:~# sudo apt update
root@uarmhf64-dev:~# sudo apt upgrade -y
root@uarmhf64-dev:~# sudo apt full-upgrade -y

Выполнение этого шага необходимо, чтобы убедиться, что запущенная установка Debian / Ubuntu на машине разработки хоста x86_64 является самой последней и установлены самые свежие ядра и пакеты.

  • Установите пакеты «net-tools» и OpenSSH-server из APT-репозитория:
root@uarmhf64-dev:~# sudo apt install -y net-tools openssh-server

«Net-tools» и «openssh-server» устанавливаются для обеспечения возможности настройки сетевого интерфейса машины разработки и удаленного подключения к работающей машине разработки по протоколам SSH и FTP.

Поскольку система была обновлена ​​и все необходимые пакеты были установлены, мы можем установить и настроить определенные компиляторы и инструментальные средства.

Установка и настройка GNU GCC / G ++ - 10.x.x

1. Установите набор инструментов GNU Compilers Collection (GCC) для платформы x86_64:

root@uarmhf64-dev:~# sudo apt install -y build-essential

2. Установите кроссплатформенные инструменты GNU Arm64 / Armhf:

root@uarmhf64-dev:~# sudo apt install -y crossbuild-essential-arm64
root@uarmhf64-dev:~# sudo apt install -y crossbuild-essential-armhf

Установка кроссплатформенных инструментальных средств для аппаратных архитектур Arm64 / Armhf требуется для создания параллельного кода на C ++ 17, который использует библиотеку triSYCL на машине разработки x86_64.

3. Установите GNU GCC / G ++, OpenMP 5.0, Boost, Range-v3, POSIX Threads, стандартные библиотеки времени выполнения C / C ++, необходимые:

root@uarmhf64-dev:~# sudo apt install -y g++-10 libomp-dev libomp5 libboost-all-dev librange-v3-dev libc++-dev libc++1 libc++abi-dev libc++abi1 libpthread-stubs0-dev libpthread-workqueue-dev

4. Установите GNU GCC / G ++ - 10.x.x. кроссплатформенные компиляторы для сборки кода, ориентированные на архитектуры Arm64 / Armhf:

root@uarmhf64-dev:~# sudo apt install -y gcc-10-arm-linux-gnueabi g++-10-arm-linux-gnueabi gcc-10-arm-linux-gnueabihf g++-10-arm-linux-gnueabihf

5. Выберите «родные» x86_64-компиляторы GCC / G ++ - 10.x.x, используемые по умолчанию, обновив альтернативы:

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 1
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 2
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 1
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 2
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 3
sudo update-alternatives --set cc /usr/bin/gcc
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 3
sudo update-alternatives --set c++ /usr/bin/g++

6. Выберите кроссплатформенные компиляторы Arm / Aarch64 GCC / G ++ - 10.x.x, используемые по умолчанию, обновив альтернативы:

sudo update-alternatives --install /usr/bin/arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gcc /usr/bin/arm-linux-gnueabihf-gcc-9 1
sudo update-alternatives --install /usr/bin/arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gcc /usr/bin/arm-linux-gnueabihf-gcc-10 2
sudo update-alternatives --install /usr/bin/arm-linux-gnueabihf-g++ arm-linux-gnueabihf-g++ /usr/bin/arm-linux-gnueabihf-g++-9 1
sudo update-alternatives --install /usr/bin/arm-linux-gnueabihf-g++ arm-linux-gnueabihf-g++ /usr/bin/arm-linux-gnueabihf-g++-10 2
sudo update-alternatives --install /usr/bin/arm-linux-gnueabihf-cc arm-linux-gnueabihf-cc /usr/bin/arm-linux-gnueabihf-gcc 3
sudo update-alternatives --set arm-linux-gnueabihf-cc /usr/bin/arm-linux-gnueabihf-gcc
sudo update-alternatives --install /usr/bin/arm-linux-gnueabihf-c++ arm-linux-gnueabihf-c++ /usr/bin/arm-linux-gnueabihf-g++ 3
sudo update-alternatives --set arm-linux-gnueabihf-c++ /usr/bin/arm-linux-gnueabihf-g++

7. Наконец, проверьте, установлены ли правильные версии «родных» и кроссплатформенных инструментальных средств GNU:

root@uarmhf64-dev:~# gcc --version && g++ --version
root@uarmhf64-dev:~# arm-linux-gnueabihf-gcc --version
root@uarmhf64-dev:~# arm-linux-gnueabihf-g++ --version

8. Перейдите в каталог / opt и клонируйте дистрибутив библиотеки Khronos triSYCL из репозитория GitHub:

root@uarmhf64-dev:~# cd /opt
root@uarmhf64-dev:~# git clone --recurse-submodules https://github.com/triSYCL/triSYCL

Следующие команды создадут подкаталог / opt / triSYCL, содержащий источники дистрибутива библиотеки triSYCL.

9. Скопируйте файлы заголовков C ++ библиотеки triSYCL из каталога / opt / triSYCL / include в его расположение по умолчанию / usr / include / c ++ / 10 / на машине разработки, используя команду «rsync»:

root@uarmhf64-dev:~# cd /opt/triSYCL
root@uarmhf64-dev:~# sudo rsync -r ./ include/ /usr/include/c++/10/

10. Задайте переменные среды, необходимые для использования библиотеки triSYCL с ранее установленным кроссплатформенным набором инструментов GNU:

export CPLUS_INCLUDE_PATH=/usr/include/c++/10
env CPLUS_INCLUDE_PATH=/usr/include/c++/10
sudo echo "export CPLUS_INCLUDE_PATH=/usr/include/c++/10" >> /root/.bashrc

11. Выполните простую очистку, удалив подкаталог / opt / triSYCL:

root@uarmhf64-dev:~# rm -rf /opt/triSYCL

12. Соберите пример кода «hello.cpp», используя «родной» компилятор GNU GCC / G ++ x86_64:

root@uarmhf64-dev:~# g++ -std=c++17 -o hello hello.cpp -lpthread -lstdc++

Для построения специального кода на C ++ 17 / 2x0, использующего библиотеку Khronos triSYCL, требуются потоки POSIX и связь времени выполнения стандартных библиотек C ++.

13. Создайте пример кода «hello.cpp», используя кроссплатформенный компилятор GNU GCC / G ++:

root@uarmhf64-dev:~# arm-linux-gnueabihf-g++ -std=c++17 -o hello_rpi4b hello.cpp -lpthread -lstdc++

Поскольку мы успешно сгенерировали исполняемый код для архитектур Arm / Aarch64, загрузите исполняемый файл с машины для разработки по протоколу FTP или SSH, используя приложение MobaXterm. После этого загрузите исполняемый файл hello_rpi4b с помощью другого сеанса SSH на плату Raspberry Pi.

Чтобы запустить исполняемый файл «hello_rpi4b», используйте следующую команду в bash-console Raspbian, например:

root@uarmhf64-dev:~# chmod +rwx hello_rpi4b
root@uarmhf64-dev:~# ./hello_rpi4b > output.txt && cat output.txt

Это создаст и добавит вывод в файл «output.txt», распечатав его содержимое в консоли bash:

Hello from triSYCL on Rasberry Pi 4B+!!!
Hello from triSYCL on Rasberry Pi 4B+!!!
Hello from triSYCL on Rasberry Pi 4B+!!!
Hello from triSYCL on Rasberry Pi 4B+!!!
Hello from triSYCL on Rasberry Pi 4B+!!!

Примечание. Обычно первый метод не требует сборки дистрибутива библиотеки Khronos triSYCL из исходных текстов, если вы не планируете использовать triSYCL с другими библиотеками HPC, такими как OpenCL, OpenMP или TBB. Для получения дополнительной информации об использовании triSYCL вместе с другими библиотеками обратитесь к следующим рекомендациям и документации https://github.com/triSYCL/triSYCL/blob/master/doc/cmake.rst.

Использование дистрибутива библиотеки с открытым исходным кодом hipSYCL Акселя Алпая и LLVM / Clang-9.x.x. «Родной» набор инструментов компилятора, ориентированный на архитектуру Arm / Aarch64, является вторым методом, который позволяет создать код CL / SYCL на C ++ 17 / 2x0 для его запуска на платах Raspberry Pi. Собственная сборка конкретного кода возможна только в том случае, если на плате Raspberry Pi установлены как набор инструментов LLVM / Clang-9.x.x, так и дистрибутив библиотеки hipSYCL, а не сама машина разработки x86_64.

Далее мы обсудим все, что необходимо знать для установки и настройки инструментальной цепочки компилятора LLVM / Clang-9.x.x на плате Raspberry Pi и создания библиотеки hipSYCL Акселя Алпая из исходных текстов.

Установка и настройка LLVM / Clang-9.x.x

Перед использованием дистрибутива библиотеки Aksel Alpay hipSYCL необходимо правильно установить и настроить определенные компиляторы LLVM / Clang-9.x.x и инструментальные средства Arm / Aarch64. Для этого убедитесь, что вы выполнили ряд шагов, перечисленных ниже:

1. Обновите APT-репозитории Raspbian и установите следующие необходимые пакеты:

root@raspberrypi4:~# sudo apt update
root@raspberrypi4:~# sudo apt install -y bison flex python python3 snap snapd git wget

Приведенная выше команда установит альтернативный менеджер пакетов snap, необходимый для установки правильной версии утилиты cmake ›= 3.18.0, а также дистрибутивов python, python3 и bison, flex. ', необходимые для создания проекта с открытым исходным кодом hipSYCL «с нуля» с помощью утилиты cmake.

2. Установите утилиту «cmake» ›= 3.18.0 и демон LLVM / Clang с помощью диспетчера пакетов« snap »:

root@raspberrypi4:~# sudo snap install cmake --classic
root@raspberrypi4:~# sudo snap install clangd --classic

После установки утилиты «cmake» давайте проверим, работает ли она и была ли установлена ​​правильная версия из репозитория «snap», используя следующую команду:

root@raspberrypi4:~# sudo cmake --version

После выполнения этой команды вы должны увидеть следующий вывод:

cmake version 3.18.4
CMake suite maintained and supported by Kitware (kitware.com/cmake).

3. Установите последние версии стандартных библиотек времени выполнения Boost, POSIX-Threads и C / C ++ для цепочки инструментов LLVM / Clang:

root@raspberrypi4:~# sudo apt install -y libc++-dev libc++1 libc++abi-dev libc++abi1 libpthread-stubs0-dev libpthread-workqueue-dev
root@raspberrypi4:~# sudo apt install -y clang-format clang-tidy clang-tools clang libc++-dev libc++1 libc++abi-dev libc++abi1 libclang-dev libclang1 liblldb-dev libllvm-ocaml-dev libomp-dev libomp5 lld lldb llvm-dev llvm-runtime llvm python-clang libboost-all-dev

4. Загрузите и добавьте ключ безопасности APT-репозиториев LLVM / Clang:

root@raspberrypi4:~# wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -

5. Добавьте URL-адреса репозитория LLVM / Clang в список источников APT:

root@raspberrypi4:~# echo "deb http://apt.llvm.org/buster/ llvm-toolchain-buster main" >> /etc/apt/sources.list.d/raspi.list
root@raspberrypi4:~# echo "deb-src http://apt.llvm.org/buster/ llvm-toolchain-buster main" >> /etc/apt/sources.list.d/raspi.list

Выполнение этих двух предыдущих шагов 4 и 5 необходимо, чтобы иметь возможность установить LLVM / Clang-9.x.x. Компиляторы и определенные инструменты из определенного репозитория APT.

6. Удалите существующие символические ссылки на предыдущие версии LLVM / Clang, установленные:

root@raspberrypi4:~# cd /usr/bin && rm -f clang clang++

7. Обновите APT-репозитории еще раз и установите компиляторы, отладчик и компоновщик LLVM / Clang:

root@raspberrypi4:~# sudo apt update
root@raspberrypi4:~# sudo apt install -y clang-9 lldb-9 lld-9

8. Создайте соответствующие символические ссылки на установленные компиляторы «clang-9» и «clang ++ - 9»:

root@raspberrypi4:~# cd /usr/bin && ln -s clang-9 clang
root@raspberrypi4:~# cd /usr/bin && ln -s clang++-9 clang++

9. Наконец, у вас должна быть возможность использовать команды clang и clang ++ в консоли bash:

root@raspberrypi4:~# clang --version && clang++ --version

Здесь давайте проверим версию установленного LLVM / Clang с помощью приведенной выше команды.

После использования команд вы должны увидеть следующий вывод:

clang version 9.0.1-6+rpi1~bpo10+1
Target: armv6k-unknown-linux-gnueabihf
Thread model: posix
InstalledDir: /usr/bin
clang version 9.0.1-6+rpi1~bpo10+1
Target: armv6k-unknown-linux-gnueabihf
Thread model: posix
InstalledDir: /usr/bin

Загрузка и сборка распространения библиотеки hipSYCL

Еще один важный шаг - это загрузка и сборка промежуточного дистрибутива библиотеки hipSYCL с открытым исходным кодом из ее источников, представленных на GitHub.

Обычно это делается путем выполнения следующих шагов:

1. Загрузите дистрибутив проекта hipSYCL, клонируя его с GitHub:

root@raspberrypi4:~# git clone https://github.com/llvm/llvm-project llvm-project
root@raspberrypi4:~# git clone --recurse-submodules https://github.com/illuhad/hipSYCL

Дистрибутив проекта Aksel Alpay hipSYCL имеет несколько зависимостей от другого проекта с открытым исходным кодом LLVM / Clang. Вот почему нам обычно нужно клонировать оба дистрибутива, чтобы создать среду выполнения библиотеки hipSYCL «с нуля».

2. Задайте количество переменных среды, необходимых для создания проекта hipSYCL из исходных текстов, используя команды «export» и «env», а также добавив указанные ниже строки в сценарий профиля .bashrc:

export LLVM_INSTALL_PREFIX=/usr
export LLVM_DIR=~/llvm-project/llvm
export CLANG_EXECUTABLE_PATH=/usr/bin/clang++
export CLANG_INCLUDE_PATH=$LLVM_INSTALL_PREFIX/include/clang/9.0.1/include
echo "export LLVM_INSTALL_PREFIX=/usr" >> /root/.bashrc
echo "export LLVM_DIR=~/llvm-project/llvm" >> /root/.bashrc
echo "export CLANG_EXECUTABLE_PATH=/usr/bin/clang++" >> /root/.bashrc
echo "export CLANG_INCLUDE_PATH=$LLVM_INSTALL_PREFIX/include/clang/9.0.1/include" >> /root/.bashrc
env LLVM_INSTALL_PREFIX=/usr
env LLVM_DIR=~/llvm-project/llvm
env CLANG_EXECUTABLE_PATH=/usr/bin/clang++
env CLANG_INCLUDE_PATH=$LLVM_INSTALL_PREFIX/include/clang/9.0.1/include

3. Создайте и перейдите в подкаталог ~ / hipSYCL / build в основном каталоге проекта hipSYCL:

root@raspberrypi4:~# mkdir ~/hipSYCL/build && cd ~/hipSYCL/build

4. Сконфигурируйте исходники проекта hipSYCL с помощью утилиты cmake:

root@raspberrypi4:~# cmake -DCMAKE_INSTALL_PREFIX=/opt/hipSYCL ..

5. Соберите и установите библиотеку времени выполнения hipSYCL, используя команду GNU «make»:

root@raspberrypi4:~# make -j $(nproc) && make install -j $(nproc)

6. Скопируйте библиотеку времени выполнения libhipSYCL-rt.iso в расположение библиотек Raspbian по умолчанию:

root@raspberrypi4:~# cp /opt/hipSYCL/lib/libhipSYCL-rt.so /usr/lib/libhipSYCL-rt.so

7. Задайте переменные среды, необходимые для использования библиотеки времени выполнения hipSYCL и компиляторов LLVM / Clang для сборки исходного кода:

export PATH=$PATH:/opt/hipSYCL/bin
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/opt/hipSYCL/include
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/opt/hipSYCL/include
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/hipSYCL/lib
echo "export PATH=$PATH:/opt/hipSYCL/bin" >> /root/.bashrc
echo "export C_INCLUDE_PATH=$C_INCLUDE_PATH:/opt/hipSYCL/include" >> /root/.bashrc
echo "export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/opt/hipSYCL/include" >> /root/.bashrc
echo "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/hipSYCL/lib" >> /root/.bashrc
env PATH=$PATH:/opt/hipSYCL/bin
env C_INCLUDE_PATH=$C_INCLUDE_PATH:/opt/hipSYCL/include
env CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/opt/hipSYCL/include
env LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/hipSYCL/lib

Запуск параллельного CL / SYCL-кода на C ++ 17 на Raspberry Pi 4B +

Поскольку мы, наконец, закончили установку и настройку библиотеки LLVM / Clang и hipSYCL, настоятельно рекомендуется создать и запустить исполняемый файл образца matmul_hipsycl, убедившись, что все работает нормально:

Вот наиболее распространенные шаги для создания следующего образца из исходных текстов:

rm -rf ~/sources
mkdir ~/sources && cd ~/sources
cp ~/matmul_hipsycl.tar.gz ~/sources/matmul_hipsycl.tar.gz
tar -xvf matmul_hipsycl.tar.gz
rm -f matmul_hipsycl.tar.gz

Приведенный выше набор команд создаст подкаталог ~ / source и извлечет исходные коды примеров из архива matmul_hipsycl.tar.gz.

Чтобы собрать исполняемый файл примера, используйте команду GNU «make»:

root@raspberrypi4:~# make all

Это вызовет команду clang ++ для сборки исполняемого файла:

syclcc-clang -O3 -std=c++17 -o matrix_mul_rpi4 src/matrix_mul_rpi4b.cpp -lstdc++

Эта команда скомпилирует конкретный код C ++ 17 с включенным наивысшим уровнем оптимизации кода (например, O3) и свяжет его со стандартной средой выполнения библиотеки C ++.

Примечание. Помимо среды выполнения библиотеки, собранный проект hipSYCL также предоставляет инструменты syclcc и syclcc-clang, используемые для создания параллельного кода в C ++ 17. , реализованный с использованием библиотеки hipSYCL. Использование этих инструментов немного отличается от обычного использования команд «clang» и «clang ++». Тем не менее, «syclcc» и «syclcc-clang» по-прежнему можно использовать, задав те же параметры компилятора и компоновщика, что и исходные команды «clang» и «clang ++».

После выполнения компиляции с использованием этих инструментов предоставьте привилегии выполнения файлу «matrix_mul_rpi4», сгенерированному компилятором, с помощью команды, указанной ниже:

root@raspberrypi4:~# chmod +rwx matrix_mul_rpi4

И просто запустите исполняемый файл в консоли bash:

root@raspberrypi4:~# ./matrix_mul_rpi4

После его запуска будет получен следующий результат:

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Multiplication C = A x B:
Matrix C:
323 445 243 343 363 316 495 382 463 374
322 329 328 388 378 395 392 432 470 326
398 357 337 366 386 407 478 457 520 374
543 531 382 470 555 520 602 534 639 505
294 388 277 314 278 330 430 319 396 372
447 445 433 485 524 505 604 535 628 509
445 468 349 432 511 391 552 449 534 470
434 454 339 417 502 455 533 498 588 444
470 340 416 364 401 396 485 417 496 464
431 421 325 325 272 331 420 385 419 468

Execution time: 5 ms

При желании мы можем оценить производительность выполняемого параллельного кода, установив и используя следующие утилиты:

root@raspberrypi4:~# sudo apt install -y top htop

Использование установленной утилиты «htop» позволяет визуализировать использование ЦП и системной памяти при запуске исполняемого файла параллельного кода:

Компиляторы LLVM / Clang-9.x.x и скрипт установки и настройки hipSYCL Акселя Алпая

Автоматический bash-скрипт для установки и настройки компиляторов Arm / Aarch64 LLVM / Clang-9.x.x и библиотеки Акселя Алпая hipSYCL с открытым исходным кодом.

#!/bin/sh

sudo apt update

sudo apt install -y bison flex python python3 snap snapd git wget

sudo snap install cmake --classic
sudo snap install clangd --classic

sudo apt install -y libc++-dev libc++1 libc++abi-dev libc++abi1 libpthread-stubs0-dev libpthread-workqueue-dev
sudo apt install -y clang-format clang-tidy clang-tools clang libc++-dev libc++1 libc++abi-dev libc++abi1 libclang-dev libclang1 liblldb-dev libllvm-ocaml-dev libomp-dev libomp5 lld lldb llvm-dev llvm-runtime llvm python-clang libboost-all-dev

wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -

echo "deb http://apt.llvm.org/buster/ llvm-toolchain-buster main" >> /etc/apt/sources.list.d/raspi.list
echo "deb-src http://apt.llvm.org/buster/ llvm-toolchain-buster main" >> /etc/apt/sources.list.d/raspi.list

cd ~

sudo apt update

sudo apt install -y clang-9 lldb-9 lld-9

cd /usr/bin && rm -f clang clang++

cd /usr/bin && ln -s clang-9 clang
cd /usr/bin && ln -s clang++-9 clang++

cd ~

git clone https://github.com/llvm/llvm-project llvm-project
git clone --recurse-submodules https://github.com/illuhad/hipSYCL

export LLVM_INSTALL_PREFIX=/usr
export LLVM_DIR=~/llvm-project/llvm
export CLANG_EXECUTABLE_PATH=/usr/bin/clang++
export CLANG_INCLUDE_PATH=$LLVM_INSTALL_PREFIX/include/clang/9.0.1/include

echo "export LLVM_INSTALL_PREFIX=/usr" >> /root/.bashrc
echo "export LLVM_DIR=~/llvm-project/llvm" >> /root/.bashrc
echo "export CLANG_EXECUTABLE_PATH=/usr/bin/clang++" >> /root/.bashrc
echo "export CLANG_INCLUDE_PATH=$LLVM_INSTALL_PREFIX/include/clang/9.0.1/include" >> /root/.bashrc

env LLVM_INSTALL_PREFIX=/usr
env LLVM_DIR=~/llvm-project/llvm
env CLANG_EXECUTABLE_PATH=/usr/bin/clang++
env CLANG_INCLUDE_PATH=$LLVM_INSTALL_PREFIX/include/clang/9.0.1/include

mkdir ~/hipSYCL/build && cd ~/hipSYCL/build

cmake -DCMAKE_INSTALL_PREFIX=/opt/hipSYCL ..

make -j $(nproc) && make install -j $(nproc)

cp /opt/hipSYCL/lib/libhipSYCL-rt.so /usr/lib/libhipSYCL-rt.so

export PATH=$PATH:/opt/hipSYCL/bin
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/opt/hipSYCL/include
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/opt/hipSYCL/include
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/hipSYCL/lib

echo "export PATH=$PATH:/opt/hipSYCL/bin" >> /root/.bashrc
echo "export C_INCLUDE_PATH=$C_INCLUDE_PATH:/opt/hipSYCL/include" >> /root/.bashrc
echo "export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/opt/hipSYCL/include" >> /root/.bashrc
echo "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/hipSYCL/lib" >> /root/.bashrc

env PATH=$PATH:/opt/hipSYCL/bin
env C_INCLUDE_PATH=$C_INCLUDE_PATH:/opt/hipSYCL/include
env CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/opt/hipSYCL/include
env LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/hipSYCL/lib

echo "\n*** CONGRATULATIONS!!! YOU'RE ALL SET! ***\n\n"
echo "*** BUILDING MATMUL PROJECT FOR RASPI4B+ ***\n\n"

rm -rf ~/sources

mkdir ~/sources && cd ~/sources

cp ~/matmul_hipsycl.tar.gz ~/sources/matmul_hipsycl.tar.gz

tar -xvf matmul_hipsycl.tar.gz

rm -f matmul_hipsycl.tar.gz

make all

echo "\n*** RUNNING PARALLEL MATMUL (CL/HIPSYCL) EXECUTABLE ON RASPI4B+ ***\n"

./matrix_mul_rpi4 > output.txt

cat output.txt

rm -f output.txt && cd ~

echo "\n*** SUCCESS!!! ***\n\n"

В заключение…

Микро-FPGA, а также карманные GPGPU с вычислительными возможностями, подключенные к плате IoT извне, через интерфейсы GPIO или USB, являются следующим огромным шагом на пути к параллельным вычислениям с IoT. Использование миниатюрных FPGA и GPGPU дает возможность выполнять еще более сложные и «тяжелые» вычисления параллельно, резко увеличивая фактическое ускорение производительности при обработке огромных объемов больших данных в режиме реального времени.

Очевидно, что еще одним важным аспектом параллельных вычислений с IoT является продолжение разработки конкретных библиотек и фреймворков, обеспечивающих спецификацию уровня модели CL / SYCL и, таким образом, поддержку гетерогенной вычислительной платформы (XPU). В настоящее время последние версии этих библиотек обеспечивают поддержку разгрузки выполнения параллельного кода на цели ускорения центральных процессоров, только потому, что другое оборудование для ускорения, такое как малогабаритные GPGPU и FPGA для нанокомпьютеров, еще не спроектировано и производятся его поставщиками в настоящее время.

Фактически, параллельные вычисления с Raspberry Pi и другими конкретными платами IoT представляют особый интерес для разработчиков программного обеспечения и технических специалистов по аппаратному обеспечению, которые проводят оценку производительности существующих вычислительных процессов при их параллельном запуске с IoT.

В заключение следует отметить, что использование параллельных вычислений на основе Интернета вещей обычно улучшает общую производительность облачных решений, предназначенных для сбора и массовой обработки больших данных в режиме реального времени. В результате это положительно влияет на качество машинного обучения (ML) и самой аналитики данных.