作者: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中提供。
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
// 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());
}
結論
使用Arm Compiler for Linux時,libamath通過依賴于編譯器的自動矢量化,為這些應用程序提供了利用性能的潛力。這提供了所有math.h例程的Arm優化Neon和SVE變體。我們的“優化例程”(https://github.com/ARM-software/optimized-routines)開源代碼庫提供了對更廣泛使用的例程的最新優化的訪問權限。這些矢量化算法已經用于加速計算物理、機器學習和網絡等各種應用程序中的基本數學運算。當使用這兩種方法之一時,用戶還可以使用上面描述的接口直接從其代碼中調用這些矢量例程。
-
ARM
+關注
關注
134文章
9164瀏覽量
368693 -
SPEC
+關注
關注
0文章
31瀏覽量
15826 -
數學函數
+關注
關注
0文章
9瀏覽量
6366
原文標題:在Arm上使用向量數學函數
文章出處:【微信號:Arm軟件開發者,微信公眾號:Arm軟件開發者】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論