概述
近年来 Arm 服务器的发展势头很猛,但大部分人的个人电脑还是 x86 环境,开发上存在不便。
本文介绍了如何在 x86 环境下,基于 Qemu 和 Docker 快速搭建 AARCH64 开发环境。
从 docker-hub 可以下载到一个名字叫 dev4arm64/aarch64:ubuntu\_19.04\_sve 的 docker image,
读者可以通过 AARCH64 开发环境准备 这一节提供的命令进入 AARCH64 开发环境。
也可以通过 附录 提供的方法,手动创建开发环境。
到目前为止,官方 release 的 gcc 还不支持 SVE intrinsics ,
但 github上 的 gcc-mirror 仓包含了一个 aarch64/sve-acle-branch 的分支,
通过 sve acle 分支的源代码,可以手动编译出一个支持 SVE intrinsics 的 gcc 编译器,
更多的信息见参考文献 [2]。
本文的 AARCH64 开发环境中内置了一个手动编译的 gcc,用来支持对 SVE intrinsics 的编译。
支持 SVE intrinsics 的编译器,放在了开发环境的 /home/dev/bin/gcc_sve/ 目录下面。
下文中提到的所有测试代码、支持 SVE intrinsics 的 gcc 编译器,
都已经内置在了 dev4arm64/aarch64:ubuntu\_19.04\_sve docker image 中。本文是 AARCH64 开发系列文章的第一篇。以下假定所有代码存放于 ~/work 目录下。
AARCH64 开发环境准备
准备一台安装有 ubuntu18.04 (更高版本或者近似版本都可以) 的 x86 电脑,运行如下命令进入 AARCH64 开发环境。
sudo apt-get install qemu-user
wget "https://raw.githubusercontent.com/qemu/qemu/master/scripts/qemu-binfmt-conf.sh"
sudo chmod u+x qemu-binfmt-conf.sh
sudo ./qemu-binfmt-conf.sh --qemu-path /usr/bin
sudo docker pull dev4arm64/aarch64:ubuntu_19.04_sve # get docker image
sudo docker run --rm -v ~/:/mnt -it dev4arm64/aarch64:ubuntu_19.04_sve su - dev # enter development env
以下所有内容都是在 AARCH64 开发环境中的操作,
本文的实验代码可以从参考文献 [5] 下载。
AARCH64 基本汇编编译运行
切换到目录 ~/work/aarch64_asm,有一个内置的 aarch64 的基本汇编测试程序,如下
$ cat hello.S
.arch armv8-a
.text
.align 2
.global main
.type main, %function
main:
stp x29, x30, [sp, -16]!
adrp x0, hello_str
add x0, x0, :lo12:hello_str
bl printf
mov x0, 0
ldp x29, x30, [sp], 16
ret
.section .rodata
.align 4
hello_str:
.string "hello aarch64\n"
执行 makefile 文件可以得到如下结果
$ make run clean
gcc hello.S -o hello
./hello
hello aarch64
rm -f hello *.o
AARCH64 Neon 编译运行
Neon 的测试代码在目录 ~/work/neon 下面。
AARCH64 Neon 汇编编译运行
这是一个批量处理16个 unsigned char 类型数据做加法运算的例子,运行 make run_asm clean 结果如下
$ make run_asm clean
cc -c -o neon_add3.o neon_add3.S
cc -g -Wall -march=armv8.2-a -O2 -c -o neon_add3_test.o neon_add3_test.c
cc neon_add3.o neon_add3_test.o -o neon_add3
./neon_add3
name: data
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
name: data (new)
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
rm -f *.o neon_add3 neon_hello
AARCH64 Neon intrinsics 编译运行
这是一个用neon计算 1,2,3 ... 加到99 的例子,运行 make run_intrinsics clean 结果如下
$ make run_intrinsics clean
cc -g -Wall -march=armv8.2-a -O2 -c -o neon_hello.o neon_hello.c
cc neon_hello.o -o neon_hello
./neon_hello
sum=4950
rm -f *.o neon_add3 neon_hello
AARCH64 SVE 编译运行
SVE 的测试代码在目录 ~/work/sve 下面。
AARCH64 SVE 汇编编译运行
这是通过sve指令计算字符串长度的例子,运行 make run_asm clean 结果如下
注意: arm sve 指令是 armv8.2 开始支持的,因此 -march 后面的参数是: armv8.2-a+sve
$ make run_asm clean
cc -c -o sve_strlen.o sve_strlen.S
/home/dev/bin/gcc_sve/bin/aarch64-linux-gnu-gcc -g -Wall -march=armv8.2-a+sve -O2 -c -o sve_strlen_test.o sve_strlen_test.c
cc sve_strlen.o sve_strlen_test.o -o sve_strlen
./sve_strlen
len=9 of "hello sve"
rm -f *.o sve_strlen sve_hello
因为这个例子的代码量比较少,因此贴出 source code 的源代码,更多内容,
见参考文献 [6]
$ cat sve_strlen.S
// reference: https://alastairreid.github.io/papers/sve-ieee-micro-2017.pdf
.arch armv8.2-a+sve
.text
.align 2
.global sve_strlen
.type sve_strlen, %function
sve_strlen:
mov x1, x0
ptrue p0.b
.loop:
setffr
ldff1b z0.b, p0/z, [x1]
rdffr p1.b, p0/z
cmpeq p2.b, p1/z, z0.b, #0
brkbs p2.b, p1/z, p2.b
incp x1, p2.b
b.last .loop
sub x0, x1, x0
ret
AARCH64 SVE intrinsics 编译运行
这是一个通过 sve intrinsics 做批量运算的例子,运行 make run_intrinsics clean 结果如下
$ make run_intrinsics clean
/home/dev/bin/gcc_sve/bin/aarch64-linux-gnu-gcc -g -Wall -march=armv8.2-a+sve -O2 -c -o sve_hello.o sve_hello.c
cc sve_hello.o -o sve_hello
./sve_hello
0.988095 0.988095 0.988095, 0.000000, 0.988095
1.488095 1.488095 1.488095, 0.500000, 0.988095
1.654762 1.654762 1.654762, 0.666667, 0.988095
1.738095 1.738095 1.738095, 0.750000, 0.988095
1.788095 1.788095 1.788095, 0.800000, 0.988095
1.821429 1.821429 1.821429, 0.833333, 0.988095
1.845238 1.845238 1.845238, 0.857143, 0.988095
1.863095 1.863095 1.863095, 0.875000, 0.988095
1.876984 1.876984 1.876984, 0.888889, 0.988095
1.888095 1.888095 1.888095, 0.900000, 0.988095
rm -f *.o sve_strlen sve_hello
附录
下载附件:ubuntu-19.04-dockerfile 和 docker-build.sh,
在命令行上输入如下命令,等待一段时间,环境就会创建成功。
./docker-build.sh
参考文献
[1] SVE in QEMU's linux-user mode
[4] ARM64编译工具链下载
文件名 | 大小 | 下载次数 | 操作 |
---|---|---|---|
docker-build.sh | 251B | 10 | 下载 |
ubuntu-19.04-dockerfile | 969B | 10 | 下载 |