ARM ASIMD & SVE 向量数学库接口

学校的 A64FX 机器上最近装了 ARM 官方的编译器和加速库套件,我摸了一下。令我无语的是 ARM 的手册里并没有说如何为向量数据类型使用数学函数,只是说他们的编译器可以做自动向量化。我找了一下,反而是从华为鲲鹏的网站上找到了他们的数学库函数说明(顺带吐槽一点华为的数学库也叫 SVML,和英特尔的 Short Vector Math Library 一样),其中列出的接口和此前 GCC 在 x86 平台上的 libmvec 接口命名方式相同。我又查了一下 ARM 加速库里的 libamath 的符号表,果然在里面找到了对应的 SVE 版本接口。下面是我试验过的 ASIMD & SVE 向量数学库接口列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// =============== ASIMD =============== //
float32x4_t _ZGVnN4v_logf(float32x4_t a);
float64x2_t _ZGVnN2v_log (float64x2_t a);

// Kunpeng KML_SVML does not provide vectorized log2()
float32x4_t _ZGVnN4v_log2f(float32x4_t a);
float64x2_t _ZGVnN2v_log2 (float64x2_t a);

float32x4_t _ZGVnN4v_log10f(float32x4_t a);
float64x2_t _ZGVnN2v_log10 (float64x2_t a);

float32x4_t _ZGVnN4v_expf(float32x4_t a);
float64x2_t _ZGVnN2v_exp (float64x2_t a);

float32x4_t _ZGVnN4v_exp2f(float32x4_t a);
float64x2_t _ZGVnN2v_exp2 (float64x2_t a);

// Kunpeng KML_SVML does not provide vectorized exp10()
float32x4_t _ZGVnN4v_exp10f(float32x4_t a);
float64x2_t _ZGVnN2v_exp10 (float64x2_t a);

float32x4_t _ZGVnN4v_powf(float32x4_t a, float32x4_t b);
float64x2_t _ZGVnN2v_pow (float64x2_t a, float64x2_t b);

float32x4_t _ZGVnN4v_sinf(float32x4_t a);
float64x2_t _ZGVnN2v_sin (float64x2_t a);

float32x4_t _ZGVnN4v_cosf(float32x4_t a);
float64x2_t _ZGVnN2v_cos (float64x2_t a);

// =============== SVE (no mask vector) =============== //
svfloat32_t _ZGVsNxv_logf(svfloat32_t a);
svfloat64_t _ZGVsNxv_log (svfloat64_t a);

svfloat32_t _ZGVsNxv_log2f(svfloat32_t a);
svfloat64_t _ZGVsNxv_log2 (svfloat64_t a);

svfloat32_t _ZGVsNxv_log10f(svfloat32_t a);
svfloat64_t _ZGVsNxv_log10 (svfloat64_t a);

svfloat32_t _ZGVsNxv_expf(svfloat32_t a);
svfloat64_t _ZGVsNxv_exp (svfloat64_t a);

svfloat32_t _ZGVsNxv_exp2f(svfloat32_t a);
svfloat64_t _ZGVsNxv_exp2 (svfloat64_t a);

svfloat32_t _ZGVsNxv_exp10f(svfloat32_t a);
svfloat64_t _ZGVsNxv_exp10 (svfloat64_t a);

svfloat32_t _ZGVsNxv_powf(svfloat32_t a, svfloat32_t b);
svfloat64_t _ZGVsNxv_pow (svfloat64_t a, svfloat64_t b);

svfloat32_t _ZGVsNxv_sinf(svfloat32_t a);
svfloat64_t _ZGVsNxv_sin (svfloat64_t a);

svfloat32_t _ZGVsNxv_cosf(svfloat32_t a);
svfloat64_t _ZGVsNxv_cos (svfloat64_t a);

// =============== SVE (with mask vector) =============== //
svfloat32_t _ZGVsMxv_logf(svbool_t pg, svfloat32_t a);
svfloat64_t _ZGVsMxv_log (svbool_t pg, svfloat64_t a);

svfloat32_t _ZGVsMxv_log2f(svbool_t pg, svfloat32_t a);
svfloat64_t _ZGVsMxv_log2 (svbool_t pg, svfloat64_t a);

svfloat32_t _ZGVsMxv_log10f(svbool_t pg, svfloat32_t a);
svfloat64_t _ZGVsMxv_log10 (svbool_t pg, svfloat64_t a);

svfloat32_t _ZGVsMxv_expf(svbool_t pg, svfloat32_t a);
svfloat64_t _ZGVsMxv_exp (svbool_t pg, svfloat64_t a);

svfloat32_t _ZGVsMxv_exp2f(svbool_t pg, svfloat32_t a);
svfloat64_t _ZGVsMxv_exp2 (svbool_t pg, svfloat64_t a);

svfloat32_t _ZGVsMxv_exp10f(svbool_t pg, svfloat32_t a);
svfloat64_t _ZGVsMxv_exp10 (svbool_t pg, svfloat64_t a);

svfloat32_t _ZGVsMxv_powf(svbool_t pg, svfloat32_t a, svfloat32_t b);
svfloat64_t _ZGVsMxv_pow (svbool_t pg, svfloat64_t a, svfloat64_t b);

svfloat32_t _ZGVsMxv_sinf(svbool_t pg, svfloat32_t a);
svfloat64_t _ZGVsMxv_sin (svbool_t pg, svfloat64_t a);

svfloat32_t _ZGVsMxv_cosf(svbool_t pg, svfloat32_t a);
svfloat64_t _ZGVsMxv_cos (svbool_t pg, svfloat64_t a);

还有一些数学函数也有对应的向量化版本,如 tan, atan, sinh, cosh, tanh, erf, 等等,此处未列出。在 A64FX 上,ARM 官方编译器在链接时使用 -armpl 会自动链接对应的 libamath.so,用 GCC 10.2.0 以上版本链接则需要指定 ARM Performance Libraries 的路径并手动指定链接某个 libamath_xxx.so. 在 ARM21 的相对路径 arm-allinea/21.1/arm-linux-compiler-21.1_Generic-AArch64_RHEL-8_aarch64-linux/lib 下,有若干个 libamath_xxx.so,xxx 包括 tsv110, thunderx2t99, neoverse-n1, aarch64, aarch64-sve, a64fx.

最后还是要点名批评一下 ARM,是谁给你的自信现在还要对自己基于 LLVM 的编译器和基于其他开源库的加速库收费?在自家平台上功能比你多性能比你强的英特尔 oneAPI 套装现在都已经可以随意免费下载了。

References

  1. How to vectorize math routines in Arm C/C++ Compiler
  2. How to declare custom vector routines in Arm C/C++ Compiler
  3. 华为鲲鹏加速库-数学库-KML_SVML库函数说明