張?zhí)祛?王 磊
(中原工學(xué)院 前沿信息技術(shù)研究院,鄭州 450007)
CPU 廠商紛紛推出了與自身硬件平臺(tái)相對(duì)應(yīng)的數(shù)學(xué)庫(kù)軟件,國(guó)產(chǎn)申威芯片同樣需要一個(gè)功能完備、性能優(yōu)越的數(shù)學(xué)庫(kù)軟件. 基礎(chǔ)數(shù)學(xué)函數(shù)庫(kù)用以支撐在國(guó)產(chǎn)處理器平臺(tái)上科學(xué)計(jì)算方面的應(yīng)用課題的可靠高效運(yùn)行,并作為系統(tǒng)核心支持軟件集成到單機(jī)編譯器之中. 同時(shí),基礎(chǔ)數(shù)學(xué)函數(shù)庫(kù)軟件為基礎(chǔ)語(yǔ)言編譯和優(yōu)化編程提供支撐. 目前,已經(jīng)研發(fā)了多個(gè)面向申威26010眾核處理器[1]深度優(yōu)化、符合IEEE 754 標(biāo)準(zhǔn)[2]和ISO C99 規(guī)范的高效基礎(chǔ)數(shù)學(xué)函數(shù)庫(kù)版本,并將其投入到申威1621 多核處理器中使用. 數(shù)學(xué)函數(shù)在浮點(diǎn)運(yùn)算[3]過(guò)程中,會(huì)出現(xiàn)浮點(diǎn)異常的情況,如何高效處理則至關(guān)重要. 文獻(xiàn)[4,5]充分證明了一個(gè)數(shù)值計(jì)算軟件要達(dá)到?jīng)]有浮點(diǎn)異常產(chǎn)生的效果,其實(shí)現(xiàn)困難程度巨大. 在驗(yàn)證軟件的可靠性方面,文獻(xiàn)[6–8]提出了測(cè)試工具DART,CUTE 等,其中DART 可以對(duì)任何編譯的程序進(jìn)行自動(dòng)化測(cè)試. 文獻(xiàn)[9,10]提出了浮點(diǎn)標(biāo)準(zhǔn)形式化的工具Coq,Gappa 等,文獻(xiàn)[10]提出的Gappa 使用區(qū)間算法自動(dòng)評(píng)估和傳播舍入誤差,并且演示了該工具在浮點(diǎn)程序類(lèi)中的實(shí)際使用,即為數(shù)學(xué)庫(kù)中基本函數(shù)的實(shí)現(xiàn),遺憾的是缺乏直接針對(duì)浮點(diǎn)計(jì)算實(shí)現(xiàn)的形式化分析方法. Xia 等人[11]依照浮點(diǎn)運(yùn)算規(guī)則計(jì)算出了特殊數(shù)參與運(yùn)算后的返回值,從而為浮點(diǎn)數(shù)值軟件的異常分析奠定了基石.
文獻(xiàn)[12]提出了一種新的異常處理表示法,該方法能夠以合理的效率同樣很好地滿足故障、結(jié)果分類(lèi)和監(jiān)控異常的需求. 文獻(xiàn)[13]成功實(shí)現(xiàn)應(yīng)用后,其原理的變化是微乎其微的. 文獻(xiàn)[14,15]對(duì)這類(lèi)與異常領(lǐng)域相關(guān)的學(xué)術(shù)性研究和工程性探索也進(jìn)行了詳細(xì)的對(duì)比分析. 文獻(xiàn)[16]對(duì)基于IEEE 754 規(guī)范下的浮點(diǎn)異常問(wèn)題進(jìn)行了深入研究,分析并總結(jié)出面向C 語(yǔ)言環(huán)境中的不同運(yùn)算操作的異常產(chǎn)生的條件. 以上的很多研究有一個(gè)明顯的局限性,大都基于C++,Java 等面向?qū)ο笳Z(yǔ)言實(shí)現(xiàn),缺乏基于面向匯編語(yǔ)言的實(shí)現(xiàn).
此后許瑾晨等人[17]提出了一種分段式異常處理方法,這種方法不僅是面向匯編函數(shù)而且是針對(duì)浮點(diǎn)運(yùn)算,恰好彌補(bǔ)了上述研究的局限性. 為了保證方法的高效性,其先進(jìn)行浮點(diǎn)異常編碼,然后將異常處理過(guò)程分為3 個(gè)階段,巧妙地將異常處理過(guò)程和核心運(yùn)算分離開(kāi)來(lái),并應(yīng)用于申威1621 基礎(chǔ)數(shù)學(xué)庫(kù). 吳凡[18]在基礎(chǔ)數(shù)學(xué)庫(kù)適配申威1621 的過(guò)程中為了解決fcvtdl_z 指令產(chǎn)生的INE 異常問(wèn)題,提出一種浮點(diǎn)小數(shù)取整法,提前將浮點(diǎn)小數(shù)轉(zhuǎn)換為浮點(diǎn)整數(shù),但這種方法有一定的局限性,它只可應(yīng)用于絕對(duì)值大于1 的浮點(diǎn)小數(shù),因此對(duì)于像floor 、ceil 、round 等數(shù)值函數(shù)來(lái)說(shuō),要保證定義域內(nèi)所有數(shù)據(jù)的正確性,就需要用到本文提出的數(shù)據(jù)集分段處理方法.
申威1621 作為一款高性能的多核處理器,并且具有自主知識(shí)產(chǎn)權(quán),近年來(lái)已相繼推出了與之對(duì)應(yīng)的國(guó)產(chǎn)數(shù)學(xué)軟件,但是在異常處理方面還并不完善. 而glibc數(shù)學(xué)庫(kù)作為目前最大的開(kāi)源數(shù)學(xué)庫(kù),已經(jīng)形成了一套成熟的功能體系,并且獲得了大多數(shù)CPU 廠商的認(rèn)可.為了使基礎(chǔ)數(shù)學(xué)庫(kù)更好的適配申威1621 芯片,應(yīng)用于市場(chǎng)用戶的研發(fā)以及生態(tài)體系的構(gòu)建,在讓申威數(shù)學(xué)庫(kù)保證功能上的完備性的同時(shí)兼顧其高效率,并完全通過(guò)glibc 測(cè)試集、gcc 工具鏈以及SPEC[19]等市場(chǎng)上主流的測(cè)試軟件的測(cè)試,需要先將glibc 開(kāi)源庫(kù)移植到申威平臺(tái),再把基礎(chǔ)數(shù)學(xué)庫(kù)集成到glibc 中,并用開(kāi)源測(cè)試數(shù)據(jù)集對(duì)其進(jìn)行功能測(cè)試,最后對(duì)其異常處理. 本文將針對(duì)申威1621 現(xiàn)有數(shù)學(xué)庫(kù)功能測(cè)試出的不精確異常問(wèn)題從檢測(cè)、分析和處理3 個(gè)角度詳細(xì)展開(kāi)敘述.
本文主要貢獻(xiàn):
(1)對(duì)主流開(kāi)源的glibc 測(cè)試標(biāo)準(zhǔn)和機(jī)制進(jìn)行理論研究,總結(jié)出了一套詳細(xì)測(cè)試流程,為國(guó)產(chǎn)數(shù)學(xué)庫(kù)在不同的架構(gòu)中進(jìn)行擴(kuò)展提供了可能.
(2)提出一種數(shù)據(jù)集分段式處理的方法,應(yīng)用于需要消除INE 異常的函數(shù),使基礎(chǔ)數(shù)學(xué)庫(kù)同時(shí)符合了IEEE 754 標(biāo)準(zhǔn)和glibc 測(cè)試標(biāo)準(zhǔn),經(jīng)過(guò)算法改進(jìn)后的函數(shù)平均性能加速比達(dá)到148%.
為了更加清晰的表述本文問(wèn)題,第1 節(jié)詳細(xì)介紹了glibc 的異常檢測(cè)機(jī)制,總結(jié)出一套融合異常檢測(cè)的浮點(diǎn)函數(shù)算法; 第2 節(jié)利用浮點(diǎn)控制寄存器(floatingpoint control register,FPCR)跟蹤定位非精確結(jié)果異常(inexact exception,INE)產(chǎn)生的位置并且分析其原因;第3 節(jié)提出一種數(shù)據(jù)集分段處理的思想,對(duì)數(shù)值函數(shù)進(jìn)行算法改進(jìn),高效解決了INE 異常; 第4 節(jié)進(jìn)行正確性測(cè)試和性能測(cè)試,對(duì)比INE 異常在應(yīng)用此方法前后的區(qū)別以及性能的變化情況,以此來(lái)說(shuō)明以上方法的可行性; 第5 節(jié)是總結(jié)與展望.
劉劍[20]提出了一種浮點(diǎn)異常檢測(cè)方法,通過(guò)詞法與語(yǔ)法來(lái)分析源代碼的語(yǔ)義,并利用修改規(guī)則模板,對(duì)源代碼進(jìn)行轉(zhuǎn)化,同時(shí)利用狀態(tài)標(biāo)志位記錄其檢測(cè)的行號(hào),從而生成含有浮點(diǎn)異常檢測(cè)的新程序.以上的過(guò)程有一定局限性,它只能通過(guò)半自動(dòng)的代碼轉(zhuǎn)換程序完成,且只能檢測(cè)出異常類(lèi)型以及出現(xiàn)源碼的位置.
為了更清晰的說(shuō)明如何檢測(cè)出的異常以及后續(xù)的處理方法,下面介紹glibc 數(shù)學(xué)庫(kù)的異常檢測(cè)機(jī)制,該檢測(cè)流程在進(jìn)入具體函數(shù)實(shí)現(xiàn)之前先將所有異常清除和檢測(cè)ULP 是否按照預(yù)期的方式進(jìn)行或者中止; 在經(jīng)過(guò)初始化后正式進(jìn)入具體函數(shù)的測(cè)試集進(jìn)行逐一檢測(cè),針對(duì)于某個(gè)函數(shù)的某個(gè)參數(shù)先計(jì)算其最大能允許的精度誤差; 在正常運(yùn)算的過(guò)程中,通過(guò)將調(diào)用基礎(chǔ)數(shù)學(xué)庫(kù)計(jì)算的值和glibc 給出的期望值進(jìn)行一系列對(duì)比,從而完成異常類(lèi)型、異常錯(cuò)誤碼以及計(jì)算精度問(wèn)題的檢測(cè).最后對(duì)檢測(cè)結(jié)果總數(shù)進(jìn)行統(tǒng)計(jì),輸出異常和errno 的測(cè)試數(shù)量. 其基本流程如圖1 所示.
圖1 glibc 數(shù)學(xué)庫(kù)異常測(cè)試機(jī)制
本文研究的異常檢測(cè)機(jī)制相比于現(xiàn)有的異常檢測(cè)機(jī)制,它的創(chuàng)新性在于可以在全自動(dòng)的程序中快速完成,并且檢測(cè)到的異常信息更加全面,主要異常信息包括異常類(lèi)型、異常錯(cuò)誤碼以及異常返回值,其基本算法如算法1 所示. 該算法在初始化后對(duì)不同異常的類(lèi)型,不同異常的錯(cuò)誤碼以及計(jì)算精度結(jié)果進(jìn)行檢測(cè).check_ULP 函數(shù)驗(yàn)證ulp()實(shí)現(xiàn)是否按預(yù)期運(yùn)行或中止; enable_test 函數(shù)根據(jù)異常標(biāo)記參數(shù)判斷是否需要進(jìn)行接下來(lái)的一系列的異常測(cè)試; check_exception、check_errno、ulpdiff 三個(gè)函數(shù)都是將實(shí)際值和glibc 期望的值進(jìn)行比較,如果不同則返回相應(yīng)的異常類(lèi)型、異常錯(cuò)誤碼以及誤差范圍; COUNT_ARRAY 為測(cè)試集的個(gè)數(shù),EXCEPTIONS 為異常標(biāo)記參數(shù),Computed為實(shí)際的值,expected 為glibc 期望的值.
算法1. Exception detection 1. TEST_INIT;//清除異常位的設(shè)置2. if check_ULP()≠ 0 then 3. for 1…COUNT_ARRAY do 4. if enabe_test(EXCEPTIONS)≠0 then 5. if check_exception(computed,expected)=true then 6. return E; //返回異常類(lèi)型7. end if 8. if check_errno(computed,expected)=true then 9. return E; //返回異常錯(cuò)誤碼10. end if 11. if ulpdiff (computed,expected)=true then 12. return ULP;//返回誤差范圍13. end if 14. end if 15. end for 16. end if 17. TEST_FINISH;//統(tǒng)計(jì)檢測(cè)結(jié)果
glibc 異常檢測(cè)機(jī)制可以較全面的檢測(cè)出程序中的INE 異常,為了更好的處理這些異常,本文提出了基于FPCR 寄存器的分析方法,對(duì)觸發(fā)異常的指令和算法進(jìn)行了詳細(xì)分析. gdb 作為調(diào)試工具,它可以在程序中追蹤查看變量、寄存器、內(nèi)存及堆棧,更進(jìn)一步甚至可以修改變量及內(nèi)存值. 因此,我們?cè)谶M(jìn)行浮點(diǎn)運(yùn)算時(shí),可以依托這樣功能強(qiáng)大的調(diào)試器,在不同的舍入模式下,對(duì)比FPCR 寄存器第56 位值的變化,從而定位到程序中INE 異常的觸發(fā)位置. 經(jīng)過(guò)以上分析,我們可以將觸發(fā)的INE 異常分為以下兩類(lèi):
(1)指令觸發(fā)
fcvtdl_n $f16,$f11 //觸發(fā)INE 異常
以floor 函數(shù)為例,fcvtdl_n 指令將D-浮點(diǎn)數(shù)轉(zhuǎn)化成長(zhǎng)字,結(jié)果負(fù)無(wú)窮舍入,在完成向下取整功能的同時(shí)也觸發(fā)了INE 異常.
(2)算法觸發(fā)
faddd $f16,$f1,$f10 //觸發(fā)INE 異常
以ceil 函數(shù)為例,faddd 指令計(jì)算的結(jié)果舍去了小數(shù)位,造成了結(jié)果的不精確表示. 表1 例舉了特殊數(shù)4 503 599 627 370 496 前后部分浮點(diǎn)格式的16 進(jìn)制和10 進(jìn)制的數(shù)據(jù)對(duì)應(yīng)關(guān)系,發(fā)現(xiàn)一個(gè)規(guī)律,以浮點(diǎn)數(shù)0x4330000000000000 為分界點(diǎn),對(duì)于此浮點(diǎn)數(shù)的浮點(diǎn)格式有效位每加1,其10 進(jìn)制也就加1,比如0.5 加上4 503 599 627 370 496 本該等于4 503 599 627 370 496.5,但浮點(diǎn)格式的有效位已經(jīng)無(wú)法表示如此精確的計(jì)算結(jié)果,自動(dòng)將其近似4 503 599 627 370 497,這樣就實(shí)現(xiàn)了函數(shù)ceil 向上取整的功能,同理原算法中任何一個(gè)小數(shù)加上這樣一個(gè)特殊數(shù),浮點(diǎn)格式的有效位就不足以容納精確的計(jì)算結(jié)果,從而觸發(fā)INE 異常. 后面第4 節(jié)將以round函數(shù)為例,進(jìn)一步分析這種由本身算法設(shè)計(jì)帶來(lái)的INE 異常,并提出一種數(shù)據(jù)集分段處理方法將對(duì)現(xiàn)有算法進(jìn)行改進(jìn),以達(dá)到消除這種INE 異常的目的.
表1 IEEE 754 數(shù)據(jù)轉(zhuǎn)換
數(shù)據(jù)集分段處理的核心就是首先進(jìn)行輸入?yún)?shù)檢測(cè),如果遇到無(wú)窮、非數(shù)等異常數(shù)直接處理并結(jié)束程序; 如果檢測(cè)到的是浮點(diǎn)有限數(shù),則根據(jù)數(shù)據(jù)集不同的定義域區(qū)間分別處理并返回.
依據(jù) IEEE-754 的規(guī)范標(biāo)準(zhǔn),在十進(jìn)制數(shù)運(yùn)算的四舍五入中,round函數(shù)的使用功能介紹為根據(jù)四舍五入取整數(shù)原則選擇最貼近x的整數(shù). 在申威1621 處理器現(xiàn)有的基礎(chǔ)數(shù)學(xué)庫(kù)中,round函數(shù)現(xiàn)有算法流程圖如圖2 所示.
圖2 round 函數(shù)現(xiàn)有算法流程圖
現(xiàn)有round函數(shù)的算法都是先判斷輸入值是否大于特殊數(shù)4 503 599 627 370 496,大于這個(gè)特殊數(shù)的值寄存器會(huì)根據(jù)默認(rèn)的舍入模式進(jìn)行舍入,因此直接返回即可. 小于這個(gè)特殊數(shù)的輸入值,會(huì)經(jīng)過(guò)加值、修改舍入模式、截?cái)嗌崛? 步完成函數(shù)的功能.
Step 1. 加值
在輸入值的基礎(chǔ)上加上一個(gè)值的大小為0.5 的數(shù),其符號(hào)位與輸入值的符號(hào)位保持一致.
Step 2. 修改舍入模式
先用rfpcr 指令讀取浮點(diǎn)舍入模式的狀態(tài)標(biāo)志位,然后通過(guò)移位、與非等邏輯操作修改浮點(diǎn)舍入模式的狀態(tài)標(biāo)志位,最后用wfpcr 指令將其寫(xiě)回,從而將四舍五入改為向0 舍入.
Step 3. 截?cái)嗌崛?/p>
通過(guò)加上特殊數(shù)4 503 599 627 370 496,舍去小數(shù)位.
經(jīng)過(guò)以上3 步,原本是1.0–1.4 的小數(shù)加上0.5 再截?cái)嗌崛刖蜑?,1.5–1.9 的小數(shù)加上0.5 再截?cái)嗌崛雱t為2,從而實(shí)現(xiàn)了小數(shù)域四舍五入的功能. 然而,在第3 步截?cái)嗌崛霑r(shí),用faddd 指令舍去小數(shù)位的同時(shí),也造成了計(jì)算結(jié)果的不精確表示,引發(fā)了INE 異常,下面運(yùn)用數(shù)據(jù)集分段處理的思想,詳細(xì)闡述如何消除此處的INE 異常. 改進(jìn)后round 函數(shù)算法流程如圖3 所示.
圖3 相比于現(xiàn)有的算法,利用申威1621 處理器的硬件特性,首先通過(guò)以下代碼段對(duì)異常數(shù)檢測(cè)并處理,然后根據(jù)數(shù)據(jù)集不同的定義域區(qū)間分別處理并返回.
圖3 改進(jìn)后round 函數(shù)算法流程
對(duì)于絕對(duì)值小于的1 的浮點(diǎn)小數(shù)來(lái)說(shuō),四舍五入的實(shí)現(xiàn)主要和指數(shù)有關(guān),若浮點(diǎn)數(shù)的指數(shù)減去1 023 的十進(jìn)制值是–1,那么浮點(diǎn)小數(shù)的絕對(duì)值應(yīng)為[0.5,1),若浮點(diǎn)數(shù)的指數(shù)減去1 023 的十進(jìn)制值小于–1,那么浮點(diǎn)小數(shù)的絕對(duì)值應(yīng)為[0,0.5).
數(shù)值大于 1 的浮點(diǎn)數(shù),整數(shù)和小數(shù)位共同構(gòu)建了浮點(diǎn)數(shù)的尾數(shù)位,其中構(gòu)成浮點(diǎn)數(shù)整數(shù)部分的位數(shù)和浮點(diǎn)數(shù)的指數(shù)位密切相關(guān). 從雙精度浮點(diǎn)數(shù)的數(shù)據(jù)類(lèi)型不難得出,如果浮點(diǎn)數(shù)的指數(shù)位減去值為1 023 后的數(shù)表示為x,那么小數(shù)部分占用尾數(shù)的 0~(51–x)位,尾數(shù)(51–x)+1~51 則用來(lái)表示整數(shù). 如果將小數(shù)點(diǎn)后的所有數(shù)字都更改為零,則會(huì)得到小數(shù)點(diǎn)后的整數(shù). 同樣相對(duì)于絕對(duì)值大于1 的二進(jìn)制數(shù)字而言,將小數(shù)點(diǎn)后面的位全部置為 0,也就是將雙精度浮點(diǎn)數(shù)的[0,51–x]位置0,則該二進(jìn)制浮點(diǎn)數(shù)就變成了一個(gè)浮點(diǎn)整數(shù)[18].
下面重點(diǎn)介紹round函數(shù)數(shù)據(jù)集分段處理中所使用的整數(shù)判斷法和四舍五入取整法的具體步驟.
假設(shè)是對(duì)雙精度浮點(diǎn)數(shù)f1 進(jìn)行整數(shù)位的判斷:
Step 1. 將f1 傳進(jìn)二進(jìn)制數(shù)t1; 再將t1 右移52 位得到t0;生成一個(gè)十進(jìn)制值為2 047 的t2,將t2 與t0 相與得到f1 指數(shù)位的十進(jìn)制值x1.
Step 2. 將x1 和十進(jìn)制為 1 023 的值相減,計(jì)算出浮點(diǎn)數(shù)的尾數(shù)部分整數(shù)占據(jù)的位數(shù)n.
Step 3. 構(gòu)造符號(hào)位、指數(shù)位全0,尾數(shù)位全1 的二進(jìn)制數(shù)t3; 再將其右移n位,得到尾數(shù)位表示整數(shù)位
Step 4. 將t3 和t1 進(jìn)行邏輯與操作; 如果浮點(diǎn)數(shù)f1是整數(shù),那么二進(jìn)制t1 表示小數(shù)的位上應(yīng)為全0,與操作后得到數(shù)也應(yīng)為全0; 反之,則判斷浮點(diǎn)數(shù)f1 不為整數(shù).
以上算法中浮點(diǎn)小數(shù)根據(jù)四舍五入原則取最接近x整數(shù)的具體步驟如下.
如果遵循四舍五入的原則進(jìn)行取整的是雙精度浮點(diǎn)小數(shù)f1:
Step 1. 取得f1 的指數(shù)e1,取得浮點(diǎn)數(shù)1 的指數(shù)e2; 然后將e1–e2 得到的十進(jìn)制數(shù)值用n表示,從而計(jì)算出浮點(diǎn)數(shù)的整數(shù)部分所占的位數(shù).
Step 2. 構(gòu)造符號(hào)位、指數(shù)位全0,尾數(shù)位全1 的二進(jìn)制數(shù)t2; 再將t2 右移n位,計(jì)算出表示浮點(diǎn)數(shù)的整數(shù)位上全0 的二進(jìn)制t3.
Step 3. 構(gòu)造浮點(diǎn)最小值f2,將其對(duì)應(yīng)的二進(jìn)制數(shù)右移n位得到t4; 接著將t4 加上t1 得到二進(jìn)制數(shù)t1,完成了四舍五入前的加值操作.
Step 4. 將表示浮點(diǎn)數(shù)整數(shù)位上全0 的二進(jìn)制t3 按位取反,得到表示小數(shù)位上全0 的二進(jìn)制數(shù)t3.
Step 5. 將二進(jìn)制數(shù)t3 與t1 相與,得到的二進(jìn)制數(shù)傳給f1,從而完成了浮點(diǎn)小數(shù)f1 的四舍五入.
其他數(shù)值函數(shù)floor,ceil,nearbyint,nextafter,算法改進(jìn)的方法和round函數(shù)類(lèi)似. 用開(kāi)源測(cè)試數(shù)據(jù)集測(cè)試的INE 異常不需要設(shè)置的所有函數(shù),通過(guò)這樣的算法改進(jìn),完全可以消除INE 異常.
為了更直觀地驗(yàn)證本文采用的數(shù)據(jù)集分段處理方法的可行性,將測(cè)試平臺(tái)選為申威 1621 處理器,表2詳盡的例舉出了處理器相關(guān)配置信息.
表2 申威1621 實(shí)驗(yàn)平臺(tái)
浮點(diǎn)計(jì)算程序的正確性和性能都得到了驗(yàn)證. 正確性測(cè)試根據(jù) glibc 異常檢測(cè)機(jī)制,將異常處理前后的計(jì)算結(jié)果進(jìn)行比較; 性能測(cè)試分別對(duì)異常處理前和異常處理后的測(cè)試結(jié)果進(jìn)行對(duì)比,并求得經(jīng)過(guò)算法改進(jìn)后的函數(shù)平均加速比.
注意這里性能加速比的計(jì)算公式和其他文獻(xiàn)計(jì)算的方式不同,具體如下:
性能加速比=(算法改進(jìn)前節(jié)拍/算法改進(jìn)后節(jié)拍)×100%
在驗(yàn)證glibc-2.28 libm 和基礎(chǔ)數(shù)學(xué)庫(kù)函數(shù)功能是否一致的過(guò)程中,用開(kāi)源測(cè)試數(shù)據(jù)集測(cè)試出基礎(chǔ)函數(shù)庫(kù)中INE 異常需要消除的函數(shù),圖4 以double 類(lèi)型為例,例舉了5 個(gè)不同函數(shù)INE 異常需要消除的測(cè)試集個(gè)數(shù),橫坐標(biāo)表示了函數(shù)名稱(chēng),縱坐標(biāo)表示引發(fā)INE 異常的測(cè)試集的數(shù)目.
圖4 INE 異常測(cè)試集統(tǒng)計(jì)
從圖4 中不難發(fā)現(xiàn),INE 異常需要消除的函數(shù)全部集中在數(shù)值函數(shù)中,通過(guò)應(yīng)用以上數(shù)據(jù)集分段處理的方法,再進(jìn)行測(cè)試則發(fā)現(xiàn)將圖4 檢測(cè)到的5 個(gè)函數(shù)不同測(cè)試集的所有INE 異常消除.
申威1621 處理器整數(shù)部件中有一個(gè)控制狀態(tài)寄存器TC,作為周期計(jì)數(shù)器. rpcc 指令作為如今超級(jí)計(jì)算機(jī)衡量性能的通用計(jì)時(shí)指令,通過(guò)插樁采樣來(lái)計(jì)算被測(cè)函數(shù)的運(yùn)算節(jié)拍數(shù)來(lái)判斷性能的高低. 為了保證性能測(cè)量結(jié)果能夠涵蓋所有被測(cè)函數(shù)的熱點(diǎn)路徑,首先進(jìn)行熱點(diǎn)分析,并檢查數(shù)據(jù)集主要使用的是隨機(jī)浮點(diǎn)數(shù),其特點(diǎn)為都在0–1 區(qū)間范圍內(nèi)均勻分布,以測(cè)試基礎(chǔ)數(shù)學(xué)庫(kù)中運(yùn)行上百次以上的總節(jié)拍數(shù)[18]. 為了排除誤差較大的測(cè)試數(shù)據(jù)對(duì)性能測(cè)試結(jié)果的干擾,采用4D 檢測(cè)法[21]對(duì)測(cè)試結(jié)果數(shù)據(jù)進(jìn)行相關(guān)處理,從而求得算術(shù)平均值. 測(cè)試結(jié)果如圖5 所示,橫坐標(biāo)表示函數(shù)名稱(chēng),縱坐標(biāo)表示函數(shù)運(yùn)行節(jié)拍數(shù).
圖5 算法改進(jìn)前后性能對(duì)比
從圖5 的性能測(cè)試結(jié)果來(lái)看,除了ceil,ceilf 以外函數(shù)的性能還是有所提升的,并且可以算出平均加速比為148%,以此證明了這種方法的高效性. floor 函數(shù)性能提升的效果最為明顯,加速比達(dá)到了213.75%,floor 函數(shù)原來(lái)算法中相比于別的同類(lèi)數(shù)值函數(shù)多了一條 SETFPEC0 指令,這個(gè)指令會(huì)導(dǎo)致流水線中斷,嚴(yán)重降低函數(shù)性能,因此算法改進(jìn)前運(yùn)行節(jié)拍數(shù)就達(dá)到了171 cycles,節(jié)拍數(shù)遠(yuǎn)遠(yuǎn)大于其他同類(lèi)數(shù)值函數(shù),從而使得性能提升最為明顯; ceilf 函數(shù)算法改進(jìn)前由于不存在任何斷流水的指令,運(yùn)行節(jié)拍數(shù)就為66 cycles,屬于同類(lèi)函數(shù)中節(jié)拍數(shù)最小,經(jīng)過(guò)數(shù)據(jù)集分段處理后,判斷分支明顯增多,導(dǎo)致性能加速比為75%,相比于異常處理前性能有一定的下降.
綜合正確性測(cè)試和性能測(cè)試的測(cè)試結(jié)果分析,可以得出數(shù)據(jù)集分段處理的方法,在保證了功能的前提下還兼顧了性能,足以說(shuō)明這種方法的有效性.
本文提出一種數(shù)據(jù)集分段處理的方法,并應(yīng)用于floor、ceil、trunc、round 等8 個(gè)數(shù)值函數(shù),同時(shí)以round函數(shù)為例進(jìn)行算法改進(jìn),歸納出其中用到的整數(shù)判斷法和四舍五入取整法. 測(cè)試結(jié)果表明,此方法消除了所有INE 異常,且相對(duì)于算法改進(jìn)前平均性能加速比達(dá)到了148%. 下一步,我們將試圖從理論檢驗(yàn)的視角全面證實(shí)本文方法的可行性,并且把以上異常處理方式推廣至更多的浮點(diǎn)運(yùn)算型數(shù)值軟件系統(tǒng)之中.