作者:Chris Goodyer 2023年5月16日
廣泛工作負載(包括許多基準測試,如SPEC)的性能依賴于基本數(shù)學(xué)例程的有效實現(xiàn)。這些例程可以通過矢量化和有效使用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上天氣預(yù)測模型的性能。
Arm優(yōu)化的標量和向量數(shù)學(xué)例程實現(xiàn)在Arm軟件/優(yōu)化例程中作為開源軟件公開提供(https://github.com/ARM-software/optimized-routines)。這些實現(xiàn)被方便地授權(quán),允許用戶在需要時直接將它們包含在其他項目中。此外,我們還將這些作為預(yù)編譯二進制文件發(fā)布,稱為Libamath,作為Arm PL和ACfL的一部分。
雖然ACfL能夠通過自動矢量化生成對矢量數(shù)學(xué)例程的調(diào)用(請參見https://developer.arm.com/documentation/101458/latest/有關(guān)使用“-fsimdmath”編譯器選項的更多詳細信息,其他編譯器可能還不允許在AArch64上發(fā)生這種情況。然而,將項目鏈接到Arm PL或在禁用自動矢量化的情況下使用ACfL構(gòu)建它仍然可以訪問矢量數(shù)學(xué)符號。Libamath隨ACfL提供,但作為單獨的庫,因此可以通過添加-lamath將項目鏈接到Libamath。
在這篇文章中,我們強調(diào)了性能可能增加的規(guī)模,詳細說明了精度要求,并詳細解釋了如何在自己的代碼中直接使用這些函數(shù)。
準確性和性能
Libamath例程的最大錯誤低于4個ULP,并且僅支持默認的舍入模式(舍入到最近,綁定到偶數(shù))。因此,與這些函數(shù)的其他矢量化實現(xiàn)類似,從libm切換到libamath會導(dǎo)致一系列例程的少量精度損失。
Neoverse V1系統(tǒng)的預(yù)期性能增益如以下2個單精度和雙精度例程圖所示。
命名和調(diào)用約定
Libamath標量例程的名稱與libm中使用的名稱相匹配,例如,單精度和雙精度指數(shù)分別稱為expf和exp。
每個向量例程都在向量ABI名稱下公開。AArch64的向量函數(shù)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節(jié))。
例如,標量、Neon和SVE單精度指數(shù)的符號分別讀作expf、_ZGVnN4v_expf和_ZGVsMxv_expf。
向量ABI 在向量ABI中,向量函數(shù)名被篡改為以下各項的串聯(lián):
'_ZGV' '_'
其中
? :標量libm函數(shù)的名稱 ? :Neon為“n”,SVE為“s”
? :“M”表示屏蔽/謂詞版本,“N”表示無屏蔽。僅為SVE定義屏蔽例程,僅為Neon定義無屏蔽例程。
? :表示以車道數(shù)表示的矢量長度的整數(shù)。對于Neon,雙精度中=‘2’,單精度中=‘4’。對于SVE,=‘x’。
? :對于1個輸入浮點或整數(shù)參數(shù),“v”用于簽名,“vv”用于2個。有關(guān)更多詳細信息,請參見AArch64的向量函數(shù)ABI(https://github.com/ARM-software/abi-aa/blob/2982a9f3b512a5bfdc9e3fea5d3b298f9165c36b/vfabia64/vfabia64.rst#451name-mangling-function)。
示例
從最新版本23.04開始,Arm Performance Libraries提供了文檔和示例程序,以展示用戶如何直接從其程序中調(diào)用矢量例程,而不依賴于自動矢量化。以下代碼片段說明了如何調(diào)用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());
}
結(jié)論
使用Arm Compiler for Linux時,libamath通過依賴于編譯器的自動矢量化,為這些應(yīng)用程序提供了利用性能的潛力。這提供了所有math.h例程的Arm優(yōu)化Neon和SVE變體。我們的“優(yōu)化例程”(https://github.com/ARM-software/optimized-routines)開源代碼庫提供了對更廣泛使用的例程的最新優(yōu)化的訪問權(quán)限。這些矢量化算法已經(jīng)用于加速計算物理、機器學(xué)習(xí)和網(wǎng)絡(luò)等各種應(yīng)用程序中的基本數(shù)學(xué)運算。當使用這兩種方法之一時,用戶還可以使用上面描述的接口直接從其代碼中調(diào)用這些矢量例程。
-
ARM
+關(guān)注
關(guān)注
134文章
9029瀏覽量
366536 -
SPEC
+關(guān)注
關(guān)注
0文章
31瀏覽量
15771 -
數(shù)學(xué)函數(shù)
+關(guān)注
關(guān)注
0文章
9瀏覽量
6330
原文標題:在Arm上使用向量數(shù)學(xué)函數(shù)
文章出處:【微信號:Arm軟件開發(fā)者,微信公眾號:Arm軟件開發(fā)者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論