在树莓派4B+物联网板上使用CL/SYCL模型规范进行C++17/2x0并行异构编程





5.00/5 (6投票s)
一本实用的指南,用于在C++17中构建针对Arm/AArch64架构的并行CL/SYCL代码,并在树莓派4B+物联网板上运行
一个自动化Linux bash脚本(*.sh),用于从源代码安装和配置GNU和LLVM/Clang的工具链以及开源triSYCL/hipSYCL库
预安装的Ubuntu 20.04 LTS主机x86_64开发虚拟机(VBox6-VHD)和Raspbian Buster 10.06 SD卡(*.img)镜像,可在Microsoft OneDrive上获取
C++17/2x0中的并行代码示例,用于评估triSYCL/hipSYCL开源库的使用,使用GNU和LLVM/Clang Arm/Aarch64工具链构建源代码,并在树莓派4B+物联网板上运行
- matmul_src_raspi4b.tar.gz - 2.7 KB
- powf_demo_trisycl.tar.gz - 974 B
- powf_demo_hipsycl.tar.gz - 937 B
本文的读者还可以评估C++17中并行代码的执行,该代码实现了Max-Miner关联规则学习(ARL)算法,使用Aksel Alpay的CL/hipSYCL库开发,在具有Arm/Aarch64硬件架构的树莓派4B+ 4GB物联网板上运行
作者类似出版物和转载
- “树莓派4B+物联网板上的并行计算变得简单”,Arthur V. Ratz,2020年11月10日
- “适用于Armv8和AArch64硬件架构的物联网板和纳米计算机的并行异构计算”,Arthur V. Ratz,2020年11月20日
目录
- 物联网规模上的并行计算(一个想法...)
- 创新树莓派4B+物联网板概览
- 设置树莓派4B物联网板
- 使用CL/SYCL编程模型开发C++17并行代码
- 配置基于Debian/Ubuntu的开发机器(x86_64)
- 安装和配置GNU的GCC/G++-10.x.x工具链
- 下载和使用Khronos CL/triSYCL库
- 安装和配置LLVM/Clang-9.x.x工具链
- 下载和安装Aksel Alpay的hipSYCL库
物联网规模上的并行计算(一个想法...)
“SYCL(发音为‘sickle’)是一个免版税、跨平台的OpenCL 2.0抽象层,它使异构处理器代码可以使用标准ISO C++编写,应用程序的主机和内核代码包含在同一个源文件中……” - Khronos® Group, Inc.,2020年。
想象一家物流公司,在全国范围内从供应商向其客户运送货物,供应商和客户通常相距遥远。该公司使用其拥有的“重型”货运卡车进行运输。在大多数情况下,货运卡车的燃油消耗是影响运输过程时间以及运输成本本身的最重要因素之一。为了受益于高质量的物流和降低的运输成本,它使用一个或多个基于IT云的软件解决方案,用于实时监控燃油消耗,并提供用于物流优化过程的数据分析。
为了提供燃油消耗的实时监控,物流公司在每辆用于运输的货运卡车上安装了带有多个连接传感器的物联网板。每个安装的物联网板都会检索各种关于货运卡车燃油消耗量的数据,并将其发送到解决方案的物联网集群中的服务器,在数据中心进行大多数处理(达到exa-scale)之前收集和预处理这些数据。在及时处理这些数据后,数据中心提供各种分析和其他推断,用于优化,例如燃油消耗和运输成本估算、最佳路线推荐等。
然而,出货量和货运量呈指数级增长,导致公司通过增加用于货运交付的卡车数量来扩大业务。因此,每辆卡车发送到物联网集群和处理exa-scale的大型数据中心的数据量一直在不断增长,始终将网络带宽以及计算节点的系统资源利用率推向极限。
将物联网集群的硬件升级到基于强大多核对称CPU和更高RAM容量的最新创新物联网板和设备,可以完全解决许多现有基于云的解决方案中系统资源耗尽和网络带宽不足的问题,这些解决方案旨在实时大规模处理大数据,从而分别显著提高数据分析质量或整个基于云解决方案的生产力。
2016年,ARM® Holdings发布了强大而创新的ARM® Cortex-A72、四核、64位RISC-V CPU,被许多物联网板供应商(如Broadcom和树莓派基金会)用于制造小型纳米计算机,这些计算机能够大规模执行复杂、时间关键和“重型”计算。
这反过来又提供了用C/C++和其他编程语言交付现代并行代码的能力,通过使用广泛的高性能计算库和框架(如OpenMP、TBB或MPI)实现大量计算过程,在最新的强大物联网板、纳米计算机上执行代码,这些板和计算机作为物联网集群和嵌入式系统的基本组成部分。
与此同时,2020年,Khronos® Group宣布了他们的CL/SYCL编程模型规范——一个OpenCL 2.0库抽象层,适用于革命性的异构计算平台(XPU),通过将复杂和“重型”工作负载的执行卸载到更多硬件加速目标(如GPGPU和FPGA),而不是仅仅依赖主机CPU,从而提供极致的并行计算性能和生产力。
此后,大量的软件开发人员开发并贡献了许多开源库发行版,例如Khronos triSYCL和Aksel Alpay的hipSYCL,它们实现了CL/SYCL编程模型规范,用于在C++17/2x0中设计并行CL/SYCL代码,并在具有Arm/Aarch64硬件架构的物联网板和纳米计算机上运行。
本文的实用指南提供了开始开发物联网集群软件所需的一切知识,该软件并行执行复杂且时间关键的计算,提供“重型”执行工作负载的可扩展性,从而显著提高边缘实时数据处理的性能和生产力
- 即开即用地设置树莓派4B+物联网板
- 使用CL/SYCL编程模型开发并行代码
- 配置基于Debian/Ubuntu的开发机器(x86_64)
- 安装和配置GNU的GCC/G++-10.x.x工具链
- 下载和安装Khronos CL/triSYCL库
- 安装和配置Arm/Aarch64 LLVM/Clang-9.x.x“原生”工具链
- 从源代码构建和安装Aksel Alpay的hipSYCL库
- 在树莓派上运行使用CL/triSYCL和hipSYCL库实现的并行代码
除了上面列出的教程和演练之外,以下文章的材料还演示并解释了几个C++17代码示例,这些示例使用CL/SYCL编程模型规范实现,执行并行矩阵乘法或将浮点数提升到特定幂。
创新树莓派4B+物联网板概览
下一代创新的树莓派4B+物联网板,基于强大的ARM多核对称64位RISC-V CPU,提供了极致的性能,从而实现了并行计算本身的终极生产力。使用最新的树莓派板可以大幅提高边缘计算过程的实际性能速度,例如实时收集和预处理数据,然后将其交付到数据中心进行exa-scale处理。并行运行这些过程显著提高了那些服务数十亿客户端请求或提供数据分析和其他推断的基于云的解决方案的效率。
在我们开始讨论如何构建和运行C++17并行代码之前,该代码是使用CL/SYCL异构编程模型规范为具有Arm/Aarch64架构的树莓派板设计的,让我们花点时间简要了解一下下一代树莓派4B+板及其技术规格
树莓派4B+物联网板采用创新的Broadcom BCM2711B0 (SoC) 芯片制造,基于最新的ARM® 四核Cortex-A72 @ 1.5GHz 64位RISC-V CPU,提供卓越的性能和可扩展性,同时将其用于边缘并行计算。
树莓派以其“可靠”和“快速”的小型纳米计算机而闻名,专为数据挖掘和并行计算而设计。ARM多核对称64位RISC-V CPU的全新硬件架构特性,如DSP、SIMD、VFPv4和硬件虚拟化支持,能够为大规模处理边缘数据的物联网集群带来显著的性能提升。
具体而言,最新树莓派4B+板最重要的优势之一是低功耗LPDDR4内存,可选择2、4或8 GiB RAM容量,以3200Mhz运行,提供通常较大的内存事务带宽,对并行计算的性能产生积极影响。强烈推荐安装4 GiB或更高RAM的板用于数据挖掘和并行计算。此外,BCM2711B0 SoC芯片还捆绑了各种集成设备和外设,例如Broadcom VideoCore VI @ 500Mhz GPU、PCI-E千兆以太网适配器等。
为了构建和运行使用CL/SYCL异构编程模型实现的特定C++17并行现代代码,我们真正需要的第一件事是安装并配置好最新Raspbian Buster 10.6操作系统的树莓派4B+物联网板。
以下是必须事先满足的硬件和软件要求简要清单
硬件
- 树莓派4 Model B0,4GB物联网板
- 16GB Micro-SD卡用于Raspbian操作系统和数据存储
- 直流电源:5.0V/2-3A,通过USB Type-C连接器供电
(最低3A - 用于数据挖掘和并行计算)
软件
- Raspbian Buster 10.6.0完整版操作系统
- Raspbian Imager 1.4
- MobaXterm 20.3 build 4396,或任何其他SSH客户端
既然我们有了树莓派4B+物联网板,现在我们可以开始即开即用地设置它了……
设置树莓派4B物联网板
在开始之前,我们必须从官方树莓派仓库下载最新版本的Raspbian Buster 10.6.0完整版操作系统镜像。为了将Raspbian操作系统镜像安装到SD卡,我们还需要下载Raspbian Imager 1.4应用程序,该应用程序适用于Windows、Linux或macOS等各种平台
此外,我们还必须下载并安装MobaXterm应用程序,用于通过SSH或FTP协议远程连接树莓派板
由于Raspbian Buster OS和Imager应用程序已成功下载并安装,我们将使用Imager应用程序执行以下操作
- 擦除SD卡,默认格式化为FAT32文件系统
- 将预装的Raspbian Buster OS镜像(*.img)提取到SD卡
由于上述步骤已成功完成,只需从读卡器中取出SD卡并将其插入树莓派板的SD卡插槽。之后,连接micro-HDMI和以太网线缆。最后,插入DC电源线连接器,并打开板子。最终,系统将启动已安装到SD卡的Raspbian Buster OS,并提示执行几个安装后步骤以进行首次使用配置。
板子通电后,请确保已完成以下所有安装后步骤
- 打开bash控制台并设置“
root
”密码pi@raspberrypi4:~ $ sudo passwd root
- 以'
root
'权限登录Raspbian bash控制台pi@raspberrypi4:~ $ sudo -s
- 使用以下命令升级Raspbian的Linux基本系统和固件
root@raspberrypi4:~# sudo apt update root@raspberrypi4:~# sudo apt full-upgrade root@raspberrypi4:~# sudo rpi-update
- 首次重启系统
root@raspberrypi4:~# sudo shutdown -r now
- 安装最新的Raspbian引导加载程序并再次重启系统
root@raspberrypi4:~# sudo rpi-eeprom-update -d -a root@raspberrypi4:~# sudo shutdown -r now
- 启动“
raspi-config
”设置工具root@raspberrypi4:~# sudo raspi-config
- 使用“
raspi-config
”工具完成以下步骤
* 更新'raspi-config'工具
* 禁用Raspbian启动时的桌面GUI
系统选项 >> 启动/自动登录 >> 控制台自动登录:
* 扩展SD卡上的根“/”分区大小
完成Raspbian安装后配置后,最后重启系统。重启后,系统将提示您登录。使用“root
”用户名和之前设置的密码,以root权限登录bash控制台。
既然您已成功登录,请在bash控制台中运行以下命令,从APT仓库安装一些软件包
root@raspberrypi4:~# sudo apt install -y net-tools openssh-server
这两个软件包是配置树莓派的网络接口或OpenSSH服务器所必需的,以便通过SSH协议使用MobaXterm远程连接到板子。
通过修改 _/etc/network/interfaces_ 来配置板的网络接口“eth0
”,例如
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
这将启用通过SSH协议登录到bash控制台的“root
”用户,无需输入密码。
最后,尝试使用MobaXterm应用程序通过网络连接板子,并打开到IP地址为192.168.87.100的主机的远程SSH会话。您还必须能够使用之前设置的凭据成功登录到Raspbian的bash控制台
使用CL/SYCL编程模型开发C++17并行代码
这是一个小例子,演示了使用CL/SYCL模型抽象层实现的C++17代码
#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内核提交到主机CPU加速目标进行执行,该目标默认使用。接下来,它调用`cl::sycl::submit(...)`方法,该方法接受一个`cl::sycl::handler{}`对象作为单一参数,用于访问提供基本内核功能的方法,这些方法基于各种并行算法,包括`cl::sycl::handler::parallel_for(...)`方法。
以下方法用于实现从正在运行的内核内部派生的紧密并行循环。该循环的每次迭代都由自己的线程并行执行。`cl::sycl::handler::parallel_for(...)`接受两个主要参数:`cl::sycl::range<>{}`对象和一个在每次循环迭代期间调用的特定lambda函数。`cl::sycl::range<>{}`对象基本定义了在处理多维数据时,当多个嵌套循环合并时,每个特定维度要执行的并行循环迭代次数。
在上面的代码中,`cl::sycl::range<1>(N){}`对象用于调度单维度的N次并行循环迭代。`cl::sycl::handler::parallel_for(...)`方法的lambda函数接受另一个`cl::sycl::id<>{}`对象的单一参数。与`cl::sycl::range<>{}`一样,该对象实现了一个向量容器,其每个元素分别是并行循环的每个维度和每次迭代的索引值。作为参数传递给lambda函数作用域中的代码,以下对象用于检索特定的索引值。lambda函数的主体包含并行处理数据的一些代码。
在将特定内核提交到队列并派生执行后,以下代码调用不带参数的`cl::sycl::wait()`方法来设置屏障同步,确保在派生的内核完成其并行工作之前,不会执行任何代码。
CL/SYCL异构编程模型效率很高,可用于许多应用程序。
然而,英特尔公司和CodePlay软件公司很快就废弃了对非“原生”x86_64硬件架构的CL/SYCL支持。这使得无法交付针对Arm/Aarch64及其他架构的、使用特定CL/SYCL库的并行C++代码。
目前,有许多CL/SYCL开源库项目,由众多开发人员和爱好者开发,为x86_64之外的更多硬件架构提供支持。
2019年,海德堡大学(德国)的Aksel Alpay实现了最新的CL/SYCL编程模型层规范库,针对各种硬件架构,包括树莓派的Arm/Aarch64架构,并将hipSYCL开源库项目分发贡献到GitHub(https://github.com/illuhad/hipSYCL)。
在本文的后续部分,我们将讨论如何安装和配置LLVM/Clang-9.x.x编译器、工具链和hipSYCL库发行版,以便基于所讨论的库交付现代C++17并行代码。
配置基于Debian/Ubuntu的开发机器(x86_64)
基本上有两种方法来构建上面介绍的C++17 CL/SYCL代码:使用GNU的GCC/G++-10.x.x跨平台工具链和x86_64基于Debian/Ubuntu的开发机器,或者“原生”地在树莓派物联网板上,安装LLVM/Clang-9.x.x,针对Arm/Aarch64硬件架构。
使用第一种方法,可以在基于Debian/Ubuntu的x86_64开发机器上,使用Khronos triSYCL库和GNU的跨平台Arm/Aarch64工具链,构建C++17/2x0中实现的源代码,然后再将其运行在树莓派上。
要部署x86_64开发机器,需要安装最新的Debian Buster 10.6.0或Ubuntu 20.04 LTS
要部署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.x.x跨平台编译器、开发工具以及Khronos triSYCL库,这些都是构建针对树莓派Arm/Aarch64架构的代码所必需的。
在安装和配置GCC/G++编译器工具链和运行时库之前,请确保已完成以下先决条件步骤
- 升级Debian/Ubuntu的Linux基本系统
root@uarmhf64-dev:~# sudo apt update root@uarmhf64-dev:~# sudo apt upgrade -y root@uarmhf64-dev:~# sudo apt full-upgrade -y
完成此步骤是为了确保x86_64主机开发机器上运行的Debian/Ubuntu安装是最新的,并且已安装最新的内核和软件包。
- 从APT仓库安装“net-tools”和OpenSSH-server软件包
root@uarmhf64-dev:~# sudo apt install -y net-tools openssh-server
安装“net-tools”和“openssh-server”是为了能够配置开发机器的网络接口,并通过SSH和FTP协议远程连接到正在运行的开发机器。
由于系统已升级且所有必需的软件包已安装,我们可以继续安装和配置特定的编译器和工具链。
安装和配置GNU的GCC/G++-10.x.x工具链
- 安装GNU编译器集合(GCC)的x86_64平台工具链
root@uarmhf64-dev:~# sudo apt install -y build-essential
- 安装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硬件架构的跨平台工具链对于在x86_64开发机器上构建使用
triSYCL
库的C++17并行代码至关重要。 - 安装所需的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
- 安装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
- 选择GCC/G++-10.x.x“原生”x86_64编译器,更新替代项,默认使用
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++
- 选择GCC/G++-10.x.x跨平台Arm/Aarch64编译器,更新替代项,默认使用
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++
- 最后,检查GNU的“原生”和跨平台工具链是否安装了正确的版本
root@uarmhf64-dev:~# gcc --version && g++ --version root@uarmhf64-dev:~# arm-linux-gnueabihf-gcc --version root@uarmhf64-dev:~# arm-linux-gnueabihf-g++ --version
下载和使用Khronos CL/triSYCL库
- 导航到 _/opt_ 目录并从GitHub仓库克隆Khronos triSYCL库发行版
root@uarmhf64-dev:~# cd /opt root@uarmhf64-dev:~# git clone --recurse-submodules https://github.com/triSYCL/triSYCL
以下命令将创建 _/opt/triSYCL_ 子目录,其中包含triSYCL库发行版的源代码。
- 使用“
rsync
”命令将triSYCL库的C++头文件从 _/opt/triSYCL/include_ 目录复制到开发机器上的默认位置 _/usr/include/c++/10/_root@uarmhf64-dev:~# cd /opt/triSYCL root@uarmhf64-dev:~# sudo rsync -r ./ include/ /usr/include/c++/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
- 通过删除 _/opt/triSYCL_ 子目录进行简单清理
root@uarmhf64-dev:~# rm -rf /opt/triSYCL
- 使用“原生”x86_64 GNU的GCC/G++编译器构建“hello.cpp”代码示例
root@uarmhf64-dev:~# g++ -std=c++17 -o hello hello.cpp -lpthread -lstdc++
构建使用Khronos triSYCL库的C++17/2x0特定代码需要POSIX线程和C++标准库运行时链接。
- 使用GNU的跨平台GCC/G++编译器构建“hello.cpp”代码示例
root@uarmhf64-dev:~# arm-linux-gnueabihf-g++ -std=c++17 -o hello_rpi4b hello.cpp -lpthread -lstdc++
由于已成功为Arm/Aarch64架构生成了可执行代码,请使用MobaXterm应用程序通过FTP或SSH协议从开发机器下载该可执行文件。之后,使用另一个SSH会话将“hello_rpi4b”可执行文件上传到树莓派板。
如何在树莓派4B+板上运行使用C++17/2x0和CL/triSYCL库交付的并行代码
要运行“hello_rpi4b”可执行文件,例如在Raspbian的bash控制台中使用以下命令
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。
使用Aksel Alpay的hipSYCL开源库发行版和LLVM/Clang-9.x.x“原生”编译器工具链,针对Arm/Aarch64架构,是第二种方法,它允许构建C++17/2x0中的CL/SYCL代码,以便在树莓派板上运行。原生构建特定代码只有在LLVM/Clang-9.x.x工具链和hipSYCL库发行版都安装在树莓派板上,而不是x86_64开发机器本身时才可能。
接下来,我们将讨论安装和配置树莓派板上的LLVM/Clang-9.x.x编译器工具链,以及从源代码构建Aksel Alpay的hipSYCL库所需的一切知识。
安装和配置LLVM/Clang-9.x.x工具链
在使用 Aksel Alpay 的 hipSYCL 库项目发行版之前,必须正确安装和配置特定的 LLVM/Clang-9.x.x 编译器和 Arm/Aarch64 工具链。为此,请确保您已完成以下列出的步骤
- 更新Raspbian的APT仓库并安装以下先决条件软件包
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”实用程序,这些都是使用“cmake
”实用程序从“零开始”构建hipSYCL开源项目所需的。 - 使用“snap”包管理器安装“cmake”>= 3.18.0实用程序和LLVM/Clang守护程序
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).
- 为LLVM/Clang工具链安装最新的Boost、POSIX-Threads和C/C++标准运行时库
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
- 下载并添加LLVM/Clang的APT仓库安全密钥
root@raspberrypi4:~# wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
- 将LLVM/Clang的仓库URL添加到APT的sources.list中
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是必要的,以便能够从特定的APT仓库安装LLVM/Clang-9.x.x编译器和特定的工具链。
- 删除已安装的LLVM/Clang旧版本的现有符号链接
root@raspberrypi4:~# cd /usr/bin && rm -f clang clang++
- 再次更新APT仓库,并安装LLVM/Clang的编译器、调试器和链接器
root@raspberrypi4:~# sudo apt update root@raspberrypi4:~# sudo apt install -y clang-9 lldb-9 lld-9
- 为已安装的“clang-9”和“clang++-9”编译器创建相应的符号链接
root@raspberrypi4:~# cd /usr/bin && ln -s clang-9 clang root@raspberrypi4:~# cd /usr/bin && ln -s clang++-9 clang++
- 最后,您应该能够在bash控制台中使用“clang”和“clang++”命令
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
从源代码下载并安装Aksel Alpay的hipSYCL库
另一个基本步骤是从贡献到GitHub的开源hipSYCL库暂存发行版下载并构建它。
这通常通过完成以下步骤来完成
- 从GitHub克隆hipSYCL项目发行版
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库运行时。
- 设置构建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
- 在hipSYCL项目的主目录下创建并切换到 _~/hipSYCL/build_ 子目录
root@raspberrypi4:~# mkdir ~/hipSYCL/build && cd ~/hipSYCL/build
- 使用“
cmake
”实用程序配置hipSYCL项目源root@raspberrypi4:~# cmake -DCMAKE_INSTALL_PREFIX=/opt/hipSYCL ..
- 使用GNU的“
make
”命令构建并安装hipSYCL运行时库root@raspberrypi4:~# make -j $(nproc) && make install -j $(nproc)
- 将 _libhipSYCL-rt.iso_ 运行时库复制到Raspbian的默认库位置
root@raspberrypi4:~# cp /opt/hipSYCL/lib/libhipSYCL-rt.so /usr/lib/libhipSYCL-rt.so
- 设置使用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
既然我们已经完成了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++
此命令将以最高代码优化级别(例如-O3)编译特定的C++17代码,并将其与C++标准库运行时链接。
注意:除了库运行时,构建的hipSYCL项目还提供了“syclcc”和“syclcc-clang”工具,用于构建使用hipSYCL库实现的C++17并行代码。这些工具的使用与“clang”和“clang++”命令的常规用法略有不同。但是,“syclcc”和“syclcc-clang”仍然可以使用,指定与原始“clang”和“clang++”命令相同的编译器和链接器选项。
如何在树莓派4B+板上运行使用C++17/2x0和hipSYCL库交付的并行代码
使用这些工具进行编译后,只需使用以下命令向编译器生成的“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
”实用程序,可以在运行并行代码可执行文件时可视化CPU和系统内存利用率
关注点
微型FPGA以及具有计算能力的袖珍GPGPU,通过GPIO或USB接口外部连接到物联网板,是物联网并行计算的下一步。使用小型FPGA和GPGPU提供了并行执行更复杂和“繁重”计算的机会,极大地提高了实际性能速度,同时实时处理海量大数据。
显然,物联网并行计算的另一个重要方面是继续开发提供CL/SYCL模型层规范并因此支持异构计算平台(XPU)的特定库和框架。目前,这些库的最新版本仅支持将并行代码执行卸载到主机CPU加速目标,因为此时,其供应商尚未设计和制造用于纳米计算机的小型GPGPU和FPGA等其他加速硬件。
事实上,基于创新ARM Cortex-A72多核64位RISC-V CPU的树莓派和其他特定物联网板的并行计算,对于软件开发人员和硬件技术人员来说,是一个特别感兴趣的焦点,他们正在对现有计算过程进行性能评估,同时在物联网上并行运行。
总之,利用基于物联网的并行计算通常有助于提高基于云的解决方案的整体性能,这些解决方案旨在实时收集和大规模处理大数据,从而积极影响机器学习(ML)和数据分析本身的质量。
致谢
ARM® Holdings Corp.于2016年设计并制造了最新的Cortex-A72 ARMv8四核64位RISC-V CPU,提供了在边缘执行并行计算的能力。树莓派(RPi)基金会团队于2019年6月发布了基于BCM2711 (SoC)芯片的下一代树莓派4B+物联网板,提高了树莓派物联网板的生产力。BCM2711 (SoC)芯片不仅捆绑了强大的下一代ARM Cortex-A72 CPU,还捆绑了各种外围设备,例如革命性的高速LPDDR4-3200Mhz 2、4、8 GiB RAM(可选),最新的Broadcom® VideoCore™ VI 500 MHz GPU,紧凑型千兆以太网卡(PCI-E),创新的低能耗USB-C 5.0V/3A DC,非常适合数据挖掘物联网板等。
GNU编译器集合(GCC)跨平台工具链的最新版本10.x.x于2020年6月发布。LLVM开发组于2020年10月发布了LLVM/Clang-11.x.x C/C++跨平台编译器的最新“稳定”版本。2020年,Khronos Group发布了CL/triSYCL库项目的开源暂存发行版,旨在用作评估CL/SYCL包装器库并向Khronos Group和ISO委员会提供反馈的测试平台。海德堡大学(德国)的Aksel Alpay发布了CL/hipSYCL库项目暂存发行版的最“稳定”版本,该版本针对各种硬件架构,包括树莓派的Arm/Aarch64。
2020年,Arthur V. Ratz在CodeProject和Intel® DevMesh开发了几个自己的项目,旨在用于物联网集群,其实现主要基于使用Khronos CL/triSYCL和Aksel Alpay的hipSYCL开源库发行版。在整个开发周期中,他评估了使用GNU和LLVM/Clang的特定工具链从源代码构建项目。随后,在2020年11月,Arthur V. Ratz发布了一个实用教程,用于开始C++17/2x0中的并行异构编程,方法是使用CL/triSYCL和hipSYCL库,以及在最新的树莓派4B+ rev. B0物联网板上(具有Arm/Aarch64架构,而非原生PC x86_64平台)构建和运行CL/SYCL代码。
历史
- 2020年11月12日——文章和CL/SYCL代码示例的第一版发布