在Arm上使用向量数学函数

作者:chris goodyer  2023年5月16日
广泛工作负载(包括许多基准测试,如spec)的性能依赖于基本数学例程的有效实现。这些例程可以通过矢量化和有效使用simd管道来利用性能。
最近的一篇博客文章(https://community.arm.com/arm-community-blogs/b/high-performance-computing-blog/posts/bringing-wrf-up-to-speed-with-arm-neoverse)描述了如何使用arm compiler for linux(acfl)和arm performance library(arm pl)中提供的sve子程序来提高neoverse v1上天气预测模型的性能。
arm优化的标量和向量数学例程实现在arm软件/优化例程中作为开源软件公开提供(https://github.com/arm-software/optimized-routines)。这些实现被方便地授权,允许用户在需要时直接将它们包含在其他项目中。此外,我们还将这些作为预编译二进制文件发布,称为libamath,作为arm pl和acfl的一部分。
虽然acfl能够通过自动矢量化生成对矢量数学例程的调用(请参见https://developer.arm.com/documentation/101458/latest/有关使用“-fsimdmath”编译器选项的更多详细信息,其他编译器可能还不允许在aarch64上发生这种情况。然而,将项目链接到arm pl或在禁用自动矢量化的情况下使用acfl构建它仍然可以访问矢量数学符号。libamath随acfl提供,但作为单独的库,因此可以通过添加-lamath将项目链接到libamath。
在这篇文章中,我们强调了性能可能增加的规模,详细说明了精度要求,并详细解释了如何在自己的代码中直接使用这些函数。
准确性和性能
libamath例程的最大错误低于4个ulp,并且仅支持默认的舍入模式(舍入到最近,绑定到偶数)。因此,与这些函数的其他矢量化实现类似,从libm切换到libamath会导致一系列例程的少量精度损失。
neoverse v1系统的预期性能增益如以下2个单精度和双精度例程图所示。
命名和调用约定
libamath标量例程的名称与libm中使用的名称相匹配,例如,单精度和双精度指数分别称为expf和exp。
每个向量例程都在向量abi名称下公开。aarch64的向量函数abi(https://github.com/arm-software/abi-aa/blob/2982a9f3b512a5bfdc9e3fea5d3b298f9165c36b/vfabia64/vfabia64.rst#451name-mangling-function)中定义的向量名称篡改与glibc的向量abi(https://sourceware.org/glibc/wiki/libmvec?action=attachfile&do=view&target=vectorabi.txt)匹配(第2.6节)。
例如,标量、neon和sve单精度指数的符号分别读作expf、_zgvnn4v_expf和_zgvsmxv_expf。
向量abi 在向量abi中,向量函数名被篡改为以下各项的串联:
'_zgv' '_'
其中
• :标量libm函数的名称 • :neon为“n”,sve为“s”
• :“m”表示屏蔽/谓词版本,“n”表示无屏蔽。仅为sve定义屏蔽例程,仅为neon定义无屏蔽例程。
• :表示以车道数表示的矢量长度的整数。对于neon,双精度中=‘2’,单精度中=‘4’。对于sve,=‘x’。
• :对于1个输入浮点或整数参数,“v”用于签名,“vv”用于2个。有关更多详细信息,请参见aarch64的向量函数abi(https://github.com/arm-software/abi-aa/blob/2982a9f3b512a5bfdc9e3fea5d3b298f9165c36b/vfabia64/vfabia64.rst#451name-mangling-function)。
示例
从最新版本23.04开始,arm performance libraries提供了文档和示例程序,以展示用户如何直接从其程序中调用矢量例程,而不依赖于自动矢量化。以下代码片段说明了如何调用neon双精度sincos、sve单精度pow和sve双精度erf。
所有标量和向量例程的声明都在头文件amath.h中提供。
#include int main(void) { // neon cos and sin (using sincos) float64x2_t vx = (float64x2_t){0.0, 0.5}; double vc[2], vs[2]; _zgvnn2vl8l8_sincos(vx, vs, vc); // sve math routines#if defined(__arm_feature_sve) // single precision pow svbool_t pg32 = svptrue_b32(); svfloat32_t svx = svdup_n_f32(2.0f); svfloat32_t svy = svdup_n_f32(3.0f); svfloat32_t svz = _zgvsmxvv_powf(svx, svy, pg32); // double precision error function svbool_t pg64 = svptrue_b64(); svfloat64_t svw = svdup_n_f64(20.0); svfloat64_t sve = _zgvsmxv_erf(svw, svptrue_b64());#endif}  
结论
使用arm compiler for linux时,libamath通过依赖于编译器的自动矢量化,为这些应用程序提供了利用性能的潜力。这提供了所有math.h例程的arm优化neon和sve变体。我们的“优化例程”(https://github.com/arm-software/optimized-routines)开源代码库提供了对更广泛使用的例程的最新优化的访问权限。这些矢量化算法已经用于加速计算物理、机器学习和网络等各种应用程序中的基本数学运算。当使用这两种方法之一时,用户还可以使用上面描述的接口直接从其代码中调用这些矢量例程。

基于I2C总线的高分辨率红外式触摸屏设计
AMD 7nm U/H系列处理器支持面容和指纹登陆
关于砷化镓晶片的湿式化学蚀刻的研究报告
华为投资暴风科技的背后
2014年平板电脑将成主宰 市场竞争激烈
在Arm上使用向量数学函数
中小企业的上云之选,华为云智能化管理引领数字化未来
高通可为用户带来数千兆的移动下载速度
过去十年全球矿企签订合同清洁能源电力达5.9GW
紫光展锐推出八核SoC智能座舱解决方案,实现智能车载的‘时刻在线’
大唐恩智浦:EIS技术商用化成功落地,新能源行业有望迎来变革
Indilinx推新SATA 6Gbps双核心控制芯片
电能质量分析的总谐波电流畸变和总需求失真
【长安CS55】智能来袭,你能抵挡得住吗?
你们了解Word2vec吗?读者一篇就够了
英创信息技术EM9280串口的技术特色及应用介绍
iphone7发布或因内存产能不足 将面临严重缺货
针对2248.2GHz应用调整MAX4
无线通信中的回声与噪声消除解决方案的介绍
智能设备爆发和IOT趋势为PXI平台带来新发展机遇