石于誠(chéng),黃建強(qiáng),邊浩東,吳 利,賈金芳,王曉英
(青海大學(xué) 計(jì)算機(jī)技術(shù)與應(yīng)用系,青海 西寧 810016)
隨著神經(jīng)網(wǎng)絡(luò)原理性研究的不斷深入以及算力逐步增強(qiáng),越來(lái)越多的深度神經(jīng)網(wǎng)絡(luò)涌現(xiàn)。例如在自然語(yǔ)言處理[1]領(lǐng)域,谷歌提出Transformer[2]模型,其本身對(duì)于梯度消失這一難題的解決以及可以進(jìn)行并行訓(xùn)練等一系列的優(yōu)勢(shì),使得大模型愈發(fā)火熱,ChatGPT[3]也是在此基礎(chǔ)上訓(xùn)練得到的。但規(guī)模龐大的深度神經(jīng)網(wǎng)絡(luò)對(duì)于模型應(yīng)用的時(shí)效性提出了更大的挑戰(zhàn),由于“存儲(chǔ)墻”[4]和“功耗墻”[5]的存在,稀疏深度神經(jīng)網(wǎng)絡(luò)[6-7]進(jìn)入研究視野,GPU 設(shè)備和稀疏深度神經(jīng)網(wǎng)絡(luò)的結(jié)合使得訓(xùn)練速度再邁上一個(gè)嶄新的臺(tái)階。
但目前稀疏深度神經(jīng)網(wǎng)絡(luò)于GPU 的運(yùn)行性能仍然存在提升空間,異構(gòu)計(jì)算平臺(tái)的運(yùn)算能力還沒(méi)有能夠得到充分發(fā)揮。雖然稀疏深度神經(jīng)網(wǎng)絡(luò)在存儲(chǔ)和計(jì)算上存在優(yōu)勢(shì),但同時(shí)也會(huì)帶來(lái)負(fù)載不均衡和空間局部性差的缺點(diǎn)。圖計(jì)算領(lǐng)域最有影響力的高級(jí)比賽之一:GraphChallenge[8],新開(kāi)設(shè)了與稀疏深度神經(jīng)網(wǎng)絡(luò)有關(guān)的賽道,2019 年的優(yōu)勝者之一,Bisson[9]等研究者將計(jì)算任務(wù)分配給GPU 不同的線程,并采用填充等方法盡量消除不同線程之間計(jì)算量的差距,并且利用NVLink 和NVSwitch 構(gòu)建出SMP 結(jié)構(gòu)的集群體系,實(shí)現(xiàn)數(shù)據(jù)的快速獲取。之后的Lin[10]等研究者進(jìn)一步使用了任務(wù)圖優(yōu)化技術(shù),將任務(wù)圖重新構(gòu)造為有向無(wú)環(huán)圖,消除重復(fù)的節(jié)點(diǎn)的計(jì)算,使得同一節(jié)點(diǎn)的計(jì)算結(jié)果可以被相關(guān)節(jié)點(diǎn)所共享。
現(xiàn)有研究者大多針對(duì)于稀疏深度神經(jīng)網(wǎng)絡(luò)并行計(jì)算時(shí)負(fù)載不均衡的問(wèn)題進(jìn)行解決,而在空間局部性方面仍然有待進(jìn)一步研究。為此本文針對(duì)稀疏深度神經(jīng)網(wǎng)絡(luò)的計(jì)算順序進(jìn)行調(diào)整,增強(qiáng)空間局部性,并結(jié)合GPU的獨(dú)特結(jié)構(gòu)以及CUDA 編程的優(yōu)化方法,最后相較于cuSPARSE 相關(guān)庫(kù)函數(shù)在網(wǎng)絡(luò)層數(shù)為480 層時(shí)獲得1.67倍的性能提升,在網(wǎng)絡(luò)層數(shù)為1 920 層時(shí)獲得2.5 倍的性能提升。
深度神經(jīng)網(wǎng)絡(luò)存在訓(xùn)練時(shí)間長(zhǎng)、速度緩慢等缺點(diǎn),對(duì)于硬件設(shè)備的要求也越來(lái)越高。為降低計(jì)算與存儲(chǔ)成本,神經(jīng)網(wǎng)絡(luò)稀疏化成為研究熱點(diǎn)。
在大規(guī)模計(jì)算過(guò)程中,存在許多冗余的參數(shù)與計(jì)算,而對(duì)于冗余內(nèi)容進(jìn)行剪枝并不會(huì)過(guò)于影響模型最終訓(xùn)練精度。Arora[11]等指出,數(shù)據(jù)集在概率統(tǒng)計(jì)上的分布可以用稀疏的網(wǎng)絡(luò)結(jié)構(gòu)表示,在對(duì)于最終激活的神經(jīng)元與具備高度輸出的聚類神經(jīng)元進(jìn)行統(tǒng)計(jì)與分析之后,可以構(gòu)建出較優(yōu)的稀疏網(wǎng)絡(luò)拓?fù)鋸亩@得更快的訓(xùn)練速度。
Cun[12]等提出了經(jīng)典的Optimal Brand Damage 算法,通過(guò)在刪除參數(shù)之后對(duì)于目標(biāo)函數(shù)的變化進(jìn)行觀測(cè)來(lái)確定每個(gè)參數(shù)實(shí)際的貢獻(xiàn)度,而參數(shù)具體對(duì)于目標(biāo)函數(shù)的影響如式(1)所示:
該式計(jì)算較為繁瑣,通過(guò)對(duì)角逼近理論可以將公式進(jìn)行簡(jiǎn)化,如式(2)所示:
每個(gè)參數(shù)的貢獻(xiàn)度則通過(guò)式(3)可以計(jì)算得到,最后將計(jì)算數(shù)值較低的參數(shù)刪去,則在保證模型訓(xùn)練精度的前提下對(duì)于模型訓(xùn)練速度進(jìn)行了提升。
神經(jīng)網(wǎng)絡(luò)稀疏化的意義不僅在于提升模型訓(xùn)練速度,對(duì)于模型的泛化能力同樣也進(jìn)行了提升。神經(jīng)網(wǎng)絡(luò)的稀疏化也不只存在于網(wǎng)絡(luò)結(jié)構(gòu)的設(shè)計(jì)層面,針對(duì)于采樣噪聲研究者們提出了正規(guī)化和一些權(quán)重懲罰[13]舉措;為了避免模型過(guò)擬合,研究者們提出了dropout[14]方法對(duì)于全連接層進(jìn)行剪枝。這些方法共同造就了深度神經(jīng)網(wǎng)絡(luò)的稀疏性,即在精度、訓(xùn)練速度與泛化能力三個(gè)方面獲取平衡。
為了節(jié)省存儲(chǔ)空間并提升計(jì)算效率,稀疏矩陣通常被壓縮存儲(chǔ),即只保留有效的非零元素進(jìn)行計(jì)算。
樸素的稀疏矩陣壓縮存儲(chǔ)格式是通過(guò)三個(gè)數(shù)組分別對(duì)于非零元素的行偏移、列偏移具體數(shù)值進(jìn)行存儲(chǔ)。但這樣的存儲(chǔ)方式顯然是冗余的,對(duì)此CSR(Compressed Sparse Row)[15]存儲(chǔ)格式進(jìn)行了優(yōu)化,雖然CSR存儲(chǔ)格式仍然使用三個(gè)數(shù)組進(jìn)行存儲(chǔ),但沒(méi)有存儲(chǔ)每個(gè)非零元素的行偏移,只標(biāo)識(shí)了稀疏矩陣中每行第一個(gè)非零元素地址和第一行的首地址之間的偏移,在數(shù)值上即表示為從第一行開(kāi)始到索引所對(duì)應(yīng)的行當(dāng)中非零元素的個(gè)數(shù)。
在此種壓縮方式下,稀疏矩陣中的非零元素的行偏移只需要根據(jù)每行的非零元素個(gè)數(shù)進(jìn)行確認(rèn)即可,列偏移和數(shù)值的存儲(chǔ)數(shù)組長(zhǎng)度仍然和稀疏矩陣中非零元素?cái)?shù)目保持一致。CSR 存儲(chǔ)格式通過(guò)這樣的方式進(jìn)一步對(duì)于存儲(chǔ)空間進(jìn)行了壓縮,也進(jìn)一步減少?gòu)臄?shù)組中讀取元素信息時(shí)所存在的數(shù)據(jù)依賴,提升可并行性,具體如圖1 所示。
圖1 CSR 壓縮存儲(chǔ)格式
GraphChallenge 給出的數(shù)據(jù)集稀疏度為0.03,分布并無(wú)明顯規(guī)律,本文對(duì)于樸素計(jì)算方式進(jìn)行調(diào)整,配合相應(yīng)存儲(chǔ)結(jié)構(gòu)獲得更好性能提升。
隨著深度學(xué)習(xí)研究的不斷深入,普通的GPU 設(shè)備已經(jīng)開(kāi)始無(wú)法滿足層數(shù)更深、參數(shù)規(guī)模更大的神經(jīng)網(wǎng)絡(luò)的訓(xùn)練,研究者們將目光轉(zhuǎn)向硬件平臺(tái)結(jié)構(gòu)的進(jìn)一步優(yōu)化,例如Google 所提出的TPU,NVIDIA 推出的DGX-2系統(tǒng)平臺(tái)。而在硬件領(lǐng)域,存在一個(gè)經(jīng)典的優(yōu)化思想:權(quán)重固定(Weight Stationary),如圖2 所示。根據(jù)Sze[16]等研究者的研究表明,神經(jīng)網(wǎng)絡(luò)在訓(xùn)練時(shí)的瓶頸在于內(nèi)存訪問(wèn),針對(duì)于全連接層而言,運(yùn)算的基本組成部分是乘法與累加操作,而每一次的乘法與累加都需要多次的存儲(chǔ)器讀取和一次的存儲(chǔ)器寫入,而這多次的訪存操作,在最壞的情況之下,都需要對(duì)于片外存儲(chǔ)器進(jìn)行訪問(wèn),而訪問(wèn)片外存儲(chǔ)器往往會(huì)帶來(lái)更多的延時(shí)。于是硬件加速器的設(shè)計(jì)者們引入層級(jí)更多的內(nèi)存架構(gòu)進(jìn)行數(shù)據(jù)的存儲(chǔ),以便于提升訪存速度。并由于神經(jīng)網(wǎng)絡(luò)的訓(xùn)練流程相對(duì)固定,將哪些數(shù)據(jù)在哪個(gè)時(shí)刻預(yù)先讀入哪個(gè)分層存儲(chǔ)器結(jié)構(gòu)中成為了運(yùn)算速度優(yōu)化的重點(diǎn)。
圖2 權(quán)重固定
上述所提及的優(yōu)化思路被稱為神經(jīng)網(wǎng)絡(luò)的數(shù)據(jù)流問(wèn)題,而權(quán)重固定便是神經(jīng)網(wǎng)絡(luò)數(shù)據(jù)流的種類之一,權(quán)重固定的具體思路是將權(quán)重讀取到存取效率較高、能量消耗更小的寄存器當(dāng)中,并減少低效的訪存操作,針對(duì)權(quán)重?cái)?shù)據(jù)盡可能實(shí)現(xiàn)更高的數(shù)據(jù)復(fù)用,并且計(jì)算所得出的部分和可以通過(guò)處理引擎陣列進(jìn)行廣播,從而進(jìn)行部分和的累加操作。
這樣的硬件設(shè)計(jì)優(yōu)化思路運(yùn)用到軟件的設(shè)計(jì)方面,即為數(shù)據(jù)重用性的增強(qiáng)。具體方法為將數(shù)據(jù)預(yù)取到訪存延遲較低的存儲(chǔ)結(jié)構(gòu)內(nèi),并最大化預(yù)取數(shù)據(jù)的使用,避免頻繁的數(shù)據(jù)讀寫替換,加速整體計(jì)算。
2.1.1 優(yōu)化實(shí)現(xiàn)
通過(guò)觀察稀疏深度神經(jīng)網(wǎng)絡(luò)的具體運(yùn)算過(guò)程,核心部分為輸入矩陣和權(quán)重矩陣的相乘。樸素算法為多次矩陣向量乘的疊加,如圖3 所示。
圖3 樸素稀疏矩陣乘法
樸素的稀疏矩陣乘法不外乎通過(guò)壓縮矩陣存儲(chǔ),提升計(jì)算效率,但核心計(jì)算順序與稠密矩陣計(jì)算一致。
這樣的計(jì)算順序是緩存不友好的,并且不具備良好的空間局部性,每次對(duì)于新的行元素的訪問(wèn)都會(huì)造成緩存不命中,并且可能造成緩存抖動(dòng)的發(fā)生。即使通過(guò)矩陣轉(zhuǎn)置變換為行元素與行元素之間的相乘,計(jì)算結(jié)果的轉(zhuǎn)置也會(huì)帶來(lái)額外的開(kāi)銷,而在大規(guī)模的矩陣乘法中,為了節(jié)省存儲(chǔ)空間,往往使用已經(jīng)開(kāi)辟的矩陣空間進(jìn)行存儲(chǔ),在此情況下,行元素將被不同行的計(jì)算所使用,無(wú)法直接將計(jì)算結(jié)果存儲(chǔ)于原位置,并且對(duì)于各個(gè)線程計(jì)算任務(wù)的劃分也會(huì)造成阻礙。
為此本文針對(duì)其計(jì)算順序進(jìn)行調(diào)整,每一次計(jì)算將輸入矩陣的一個(gè)元素分別與權(quán)重矩陣的行元素相乘,該兩兩元素相乘的結(jié)果直接保存于權(quán)重矩陣每行元素的對(duì)應(yīng)位置,接著將輸入矩陣后一元素與權(quán)重矩陣的下一行元素分別相乘,元素相乘結(jié)果分別累加于上一次計(jì)算的結(jié)果,并存儲(chǔ)于相同位置,而由于計(jì)算結(jié)果的覆蓋存儲(chǔ),每個(gè)計(jì)算任務(wù)中保留權(quán)重矩陣行元素的副本以獲得正確結(jié)果。每次遍歷輸入矩陣的一行并完成相應(yīng)計(jì)算后即可獲得矩陣相乘結(jié)果的一行數(shù)據(jù),如圖4 所示。
圖4 計(jì)算順序調(diào)整
在計(jì)算任務(wù)劃分時(shí),假如仍然按照行元素進(jìn)行劃分,在上述的計(jì)算順序調(diào)整后,每次計(jì)算仍然需要權(quán)重矩陣不同行的數(shù)據(jù),程序空間局部性差。為此選擇按列劃分計(jì)算任務(wù),并且結(jié)合分塊技術(shù),每個(gè)計(jì)算任務(wù)內(nèi)使用部分列元素計(jì)算,該部分列元素仍然預(yù)取至線程私有寄存器內(nèi)。
基于上述的計(jì)算順序與任務(wù)劃分的調(diào)整,每個(gè)計(jì)算任務(wù)內(nèi)所使用數(shù)據(jù)皆被預(yù)取至寄存器內(nèi),無(wú)需額外冗余訪存,增強(qiáng)程序局部性,提升計(jì)算性能。為了性能的進(jìn)一步提升,可為一個(gè)計(jì)算任務(wù)分配一個(gè)線程束(Warp),對(duì)于元素的遍歷相乘采用循環(huán)展開(kāi)的方式進(jìn)行計(jì)算,細(xì)化任務(wù)粒度,并且由于不同計(jì)算任務(wù)之間不存在數(shù)據(jù)依賴,無(wú)需同步等待,并行計(jì)算不會(huì)退化為串行。雖然輸入矩陣與權(quán)重矩陣都是稀疏矩陣,導(dǎo)致不同計(jì)算任務(wù)的負(fù)載不均衡,但本文對(duì)于計(jì)算任務(wù)的劃分是循環(huán)進(jìn)行,同一線程束計(jì)算不同的部分列元素,并且數(shù)據(jù)集中的非零元素并不存在上三角或是下三角等特殊分布,因此每個(gè)線程束的計(jì)算任務(wù)方差較小,緩解負(fù)載不均衡。
2.1.2 優(yōu)化結(jié)果分析
緩存命中率可以作為反映程序空間局部性的指標(biāo),在傳統(tǒng)計(jì)算方式中,由于每次需要將矩陣的行元素分別與另一矩陣的列元素相乘累加得到結(jié)果,即需要讀取兩個(gè)矩陣的一行元素與一列元素。以矩陣大小為1 024×1 024,每行平均非零元素占比為25%,緩存行(cache line)大小為64 B 為例,由于double 類型占8 B,一個(gè)緩存行可以存儲(chǔ)8 個(gè)元素,而訪問(wèn)矩陣一行元素則會(huì)出現(xiàn)32 次緩存未命中,訪問(wèn)矩陣一列元素會(huì)出現(xiàn)256 次緩存未命中,緩存命中率只有43.75%,但經(jīng)過(guò)計(jì)算順序的調(diào)整后,每次的計(jì)算只需要訪問(wèn)輸入矩陣中的一個(gè)元素與權(quán)重矩陣中一行元素,總共出現(xiàn)33 次緩存未命中,緩存命中率為87.16%,程序具備良好空間局部性。
通過(guò)調(diào)整計(jì)算順序以提高空間局部性,數(shù)據(jù)訪問(wèn)更加集中,將其預(yù)讀至讀寫延遲更低的存儲(chǔ)結(jié)構(gòu)中,能夠進(jìn)一步提升性能。CUDA 內(nèi)存模型[17]提供了分層存儲(chǔ)結(jié)構(gòu),包括寄存器、共享內(nèi)存、L1 緩存、L2 緩存和全局內(nèi)存。其中,寄存器是每個(gè)線程私有的存儲(chǔ)空間,訪問(wèn)速度最快,但容量有限;共享內(nèi)存是每個(gè)塊私有的存儲(chǔ)空間,訪問(wèn)速度比全局內(nèi)存快,容量介于寄存器與全局內(nèi)存之間;L1 緩存和L2 緩存是全局內(nèi)存的緩存,訪問(wèn)速度比全局內(nèi)存快,但容量有限;全局內(nèi)存是所有線程共享的存儲(chǔ)空間,訪問(wèn)速度最慢,但容量最大。
2.2.1 數(shù)據(jù)存儲(chǔ)優(yōu)化
出于存儲(chǔ)容量和讀寫延遲等因素的綜合考慮,本文將數(shù)據(jù)預(yù)取至共享內(nèi)存中。不讀取至寄存器主要有以下兩個(gè)原因:(1)寄存器存儲(chǔ)容量有限;(2)寄存器是每個(gè)線程所私有的,于是每個(gè)線程都需要保存一份整行數(shù)據(jù)的副本,整體容量將會(huì)超出限制。
但共享內(nèi)存存在存儲(chǔ)體沖突的可能性,為了提升內(nèi)存帶寬,共享內(nèi)存被劃分為32 個(gè)存儲(chǔ)體,不同的存儲(chǔ)體可以被同時(shí)訪問(wèn),從而實(shí)現(xiàn)流水線式的數(shù)據(jù)讀取,隱藏?cái)?shù)據(jù)讀取延時(shí)。但同時(shí)也帶來(lái)了新的問(wèn)題,假如同時(shí)有多個(gè)線程對(duì)于同一個(gè)存儲(chǔ)體進(jìn)行訪問(wèn),此時(shí)這些線程只能排隊(duì)對(duì)于存儲(chǔ)體進(jìn)行訪問(wèn),從并行讀取退化為串行讀取,此時(shí)的訪存時(shí)間將變?yōu)椴⑿性L存時(shí)間的線程訪問(wèn)數(shù)量的倍數(shù),從而對(duì)于程序性能造成負(fù)面影響,如圖5所示。
圖5 存儲(chǔ)體沖突
雖然CUDA 對(duì)于共享內(nèi)存的訪問(wèn)還支持廣播的方式,即線程束內(nèi)的所有線程都只訪問(wèn)同一個(gè)存儲(chǔ)體,被訪問(wèn)的內(nèi)容便將廣播到所有進(jìn)行訪存請(qǐng)求的線程當(dāng)中,此時(shí)雖然只需要進(jìn)行一次廣播,但由于只有一個(gè)存儲(chǔ)體被訪問(wèn),帶寬利用率較低,無(wú)法充分發(fā)揮硬件能力。所以在設(shè)計(jì)線程的具體執(zhí)行流程的時(shí)候,需要盡量保證一個(gè)存儲(chǔ)體在同一時(shí)刻只有一個(gè)線程進(jìn)行訪問(wèn)。
而由于設(shè)計(jì)者已經(jīng)將共享內(nèi)存包含的存儲(chǔ)體數(shù)量與線程束所包含的線程數(shù)目進(jìn)行了對(duì)應(yīng),本文的程序設(shè)計(jì)也相應(yīng)更加方便。在使用線程束對(duì)于共享內(nèi)存進(jìn)行訪問(wèn)之時(shí),只需要盡量使得每個(gè)線程的任務(wù)映射到各不相同的存儲(chǔ)體內(nèi)即可,盡可能降低存儲(chǔ)體沖突發(fā)生的可能性,從而獲得較高的訪存效率和較好的程序執(zhí)行性能。經(jīng)過(guò)上文計(jì)算順序的調(diào)整,輸入矩陣內(nèi)的同一列元素將同時(shí)被多個(gè)線程訪問(wèn),而不同行的同一列元素可能存儲(chǔ)于同一個(gè)存儲(chǔ)體內(nèi),使用內(nèi)存填充可以使得本位于同一存儲(chǔ)體內(nèi)的元素分布在不同存儲(chǔ)體內(nèi),如圖6所示。
圖6 內(nèi)存填充
2.2.2 數(shù)據(jù)依賴消除
本文選擇了CSR 格式作為稀疏矩陣的壓縮和存儲(chǔ)格式,因非零元素分布不規(guī)律且散亂,無(wú)特定的規(guī)律。同時(shí),CSR 格式也最適合上文所提出的計(jì)算順序。
CSR 格式的數(shù)據(jù)依賴為每行的非零元素?cái)?shù)量的計(jì)算,需要根據(jù)前一行的非零元素?cái)?shù)量計(jì)算。而本文對(duì)CSR 格式進(jìn)行了修改,因每行非零元元素個(gè)數(shù)較少,壓縮后填充為小規(guī)模的稠密矩陣,每行元素位置位于特定區(qū)間,便于直接標(biāo)記每行非零元素?cái)?shù)量,以此消除數(shù)據(jù)依賴。
在并行計(jì)算過(guò)程中,線程束在完成一行的計(jì)算任務(wù)后,只需要統(tǒng)計(jì)本次計(jì)算所產(chǎn)生的非零元素?cái)?shù)量,并直接更新相應(yīng)位置上的數(shù)值,無(wú)需進(jìn)行線程之間的同步,以此消除數(shù)據(jù)依賴。
GraphChallenge 官方所提供的性能分析指標(biāo),除了運(yùn)行時(shí)間外,還提供了運(yùn)行速度的計(jì)算,具體計(jì)算方式為:輸入矩陣的行數(shù)和連接數(shù)目的乘積,最終除以運(yùn)行時(shí)間。通過(guò)分析不同方法在不同維度的稀疏深度神經(jīng)網(wǎng)絡(luò)中的性能表現(xiàn),綜合分析不同方法的整體計(jì)算性能。
GraphChallenge 官方提供了稀疏深度神經(jīng)網(wǎng)絡(luò)訓(xùn)練的數(shù)據(jù)集,內(nèi)容包括輸入矩陣、每層的權(quán)重矩陣以及最后的訓(xùn)練結(jié)果。官方通過(guò)使用Radix-Net[18]生成了稀疏DNN,并通過(guò)隨機(jī)重復(fù)與排列的方式生成了不同維度的神經(jīng)網(wǎng)絡(luò)。本實(shí)驗(yàn)所選擇的數(shù)據(jù)集,輸入矩陣的大小為60 000×1 024,權(quán)重矩陣的大小為1 024×1 024,輸出的結(jié)果矩陣大小為60 000×1 024,表1 展示了數(shù)據(jù)集的詳細(xì)規(guī)模。
表1 數(shù)據(jù)集規(guī)模
實(shí)驗(yàn)流程即為基于GraphChallenge 所給數(shù)據(jù)集進(jìn)行稀疏深度神經(jīng)網(wǎng)絡(luò)的訓(xùn)練,具體流程如下:
(1)從數(shù)據(jù)集文件當(dāng)中,將輸入矩陣和權(quán)重矩陣的數(shù)據(jù)讀入內(nèi)存;
(2)計(jì)算出每層的輸入矩陣和權(quán)重矩陣的乘積,并對(duì)于計(jì)算結(jié)果都加上偏置的數(shù)值,接著將計(jì)算結(jié)果輸入激活函數(shù)ReLU 當(dāng)中得到最后的數(shù)據(jù);
(3)通過(guò)訓(xùn)練的結(jié)果矩陣當(dāng)中的非零元素,計(jì)算得到最終的分類結(jié)果;
(4)將獲得的分類結(jié)果和官方所提供的答案進(jìn)行對(duì)比,確認(rèn)計(jì)算結(jié)果的正確性;
(5)輸出流程(1)~(2)的具體執(zhí)行時(shí)間作為程序的性能結(jié)果。
實(shí)驗(yàn)對(duì)比是使用cuSPARSE 庫(kù)函數(shù)版本和本文利用CUDA 所實(shí)現(xiàn)優(yōu)化方法的對(duì)比,測(cè)試在集群上進(jìn)行,具體配置為:CPU Intel Xeon Silver 4110,GPU Tesla V100-PCIE-32GB,NVCC 11.2,程序開(kāi)啟了O2 優(yōu)化,具體的運(yùn)行結(jié)果如表2 所示。
表2 不同版本程序運(yùn)行時(shí)間比較
將運(yùn)行時(shí)間代入官方所提供的運(yùn)行速度的計(jì)算公式中,得到的具體結(jié)果如表3 所示,最終對(duì)比如圖7所示。
表3 不同版本程序運(yùn)行速度比較
圖7 不同版本代碼運(yùn)行結(jié)果比較
根據(jù)最終結(jié)果,可以看出將CUDA 編程的相關(guān)優(yōu)化方法與特定的計(jì)算和存儲(chǔ)優(yōu)化相結(jié)合所體現(xiàn)出的性能優(yōu)勢(shì)。而之所以隨著層數(shù)的不斷擴(kuò)大,本文所實(shí)現(xiàn)的優(yōu)化方法的性能提升同樣增大,主要原因之一在于大量的計(jì)算與數(shù)據(jù)傳輸?shù)闹丿B而產(chǎn)生的時(shí)間隱藏。同時(shí)從對(duì)比可以看出GPU 設(shè)備在計(jì)算密集型任務(wù)上相較于CPU所存在的巨大優(yōu)勢(shì),以及將計(jì)算順序的調(diào)整、相關(guān)存儲(chǔ)的優(yōu)化與CUDA 編程的相關(guān)優(yōu)化內(nèi)容相結(jié)合之后所產(chǎn)生的性能優(yōu)勢(shì),并且隨著網(wǎng)絡(luò)層數(shù)的增加,這樣的性能優(yōu)勢(shì)也變得更加明顯,驗(yàn)證了本文所實(shí)現(xiàn)的性能優(yōu)化方法的優(yōu)越性。
大模型是未來(lái)發(fā)展的趨勢(shì)之一,但如何有效降低運(yùn)行與存儲(chǔ)成本成為了關(guān)鍵問(wèn)題,而針對(duì)神經(jīng)網(wǎng)絡(luò)的稀疏化處理不僅能夠降低計(jì)算與存儲(chǔ)開(kāi)銷,還可以提升模型泛化的能力。但稀疏化同樣也帶來(lái)了負(fù)載不均衡和程序空間局部性差的問(wèn)題,于是如何對(duì)于該問(wèn)題進(jìn)行解決從而進(jìn)一步提升計(jì)算性能成為研究熱點(diǎn)。而本文對(duì)稀疏深度神經(jīng)網(wǎng)絡(luò)的計(jì)算順序進(jìn)行了調(diào)整,加強(qiáng)數(shù)據(jù)訪問(wèn)的集中性,并提升程序空間局部性,基于此使用數(shù)據(jù)預(yù)取和CUDA 編程的相應(yīng)優(yōu)化手段,進(jìn)一步獲得了性能的提升,實(shí)驗(yàn)結(jié)果也驗(yàn)證了該方法的優(yōu)越性。