AARCH64 开发系列1: AARCH64 环境搭建

首发极术社区
作者:Zhiyuan zhu
如对Arm相关技术感兴趣,欢迎私信aijishu20加入技术微信群。

概述

近年来 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

[2] 交叉编译支持SVE ACLE的gcc

[3] qemu-user-static release

[4] ARM64编译工具链下载

[5] AARCH64 sample code

[6] Alastair Reid’ page

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值