專利名稱:一種基于cuda并行環(huán)境的gpu程序優(yōu)化方法
技術(shù)領(lǐng)域:
本發(fā)明涉及一種圖形、動(dòng)畫、科學(xué)計(jì)算、地質(zhì)、生物、物理模擬等諸多領(lǐng)域的并行計(jì)算與數(shù)據(jù)處理方法,特別涉及一種基于CUDA架構(gòu)的GPU內(nèi)核程序優(yōu)化方法,屬于高性能計(jì)算領(lǐng)域。
背景技術(shù):
CUDA 架構(gòu)(Compute Unified Device Architecture)是面向 GPU (Graphic Processing Unit)圖形處理器等設(shè)備的并行計(jì)算架構(gòu),是一套在GPU上完成高性能計(jì)算的解決方案,在CUDA環(huán)境上并行編程的接口 API有CUDA C,C++,OpenCL, RapidMind等。CUDA C是基于CUDA架構(gòu)的C語(yǔ)言擴(kuò)展,程序編寫者可以方便的利用這套API進(jìn)行GPU編程。而程序的效果實(shí)現(xiàn)則依賴于程序員編寫性能高效、功能穩(wěn)定和可移植性強(qiáng)的CUDA內(nèi)核程序, CUDA內(nèi)核程序又被稱為kernel函數(shù),是在GPU上運(yùn)行的并行計(jì)算函數(shù),內(nèi)核程序的性能直接反映了程序?qū)υO(shè)備計(jì)算資源的利用情況。
目前針對(duì)CUDA內(nèi)核程序的優(yōu)化存在一些較為成熟的技術(shù),本發(fā)明重點(diǎn)整理了以下內(nèi)容
背景技術(shù)一 CUDA的技術(shù)手冊(cè)(CUDA的技術(shù)手冊(cè)以NVIDIA. CUDA C Best Practices Guide. January 2012.為主)上公布了對(duì)存儲(chǔ)器訪問(wèn)、處理器資源利用以及指令優(yōu)化的一些技術(shù)。在這套手冊(cè)中,強(qiáng)調(diào)了兩部分內(nèi)容一是通過(guò)提高以SM設(shè)備占有率為指標(biāo)的程序并行度來(lái)掩蓋指令執(zhí)行時(shí)遇到的延遲問(wèn)題;二是對(duì)以全局存儲(chǔ)器訪問(wèn)為代表的存儲(chǔ)器訪問(wèn)模式進(jìn)行較深入的優(yōu)化。但是,這些優(yōu)化技術(shù)的不足在于過(guò)多的考慮設(shè)備占有率對(duì)程序性能的影響,其提出的程序并行度也主要是線程級(jí)并行(TLP =Thread Level Parallelism),而沒(méi)有提及指令級(jí)并行(ILP !Instruction Level Parallelism)這一優(yōu)化 CUDA程序性能的重要技術(shù);同時(shí),CUDA技術(shù)手冊(cè)在考慮程序延遲時(shí)輕視了全局存儲(chǔ)器延遲外的其它延遲,這些延遲成為程序進(jìn)一步優(yōu)化工作中的重點(diǎn)。
技術(shù)背景二 =NVIDIA公司的王鵬博士提出了一套較為完整的CUDA程序優(yōu)化流程, (Peng Wang. CUDA Optimization.1n:NVIDIA GPU Technology Conference, 2010.)將性能瓶頸分為存儲(chǔ)器瓶頸、指令瓶頸和延遲瓶頸,并給出了具體的瓶頸解決方法。但是,這套優(yōu)化流程所給出的瓶頸判定標(biāo)準(zhǔn)不夠清晰明確,如指令瓶頸的判定僅有兩條1.計(jì)算密集型程序很容易成為指令瓶頸;2.將指令優(yōu)化放在存儲(chǔ)器優(yōu)化和延遲優(yōu)化之后等(具體可參見(jiàn)文獻(xiàn) Peng Wang. CUDA Optimization.1n:NVIDIA GPU Technology Conference, 2010.);同樣,在這套優(yōu)化流程中也沒(méi)有提到ILP優(yōu)化和非全局存儲(chǔ)器訪問(wèn)的延遲問(wèn)題。
背景技術(shù)三伯克利大學(xué)的Volkov在2010年GTC大會(huì)上對(duì)CUDA程序在低占有率下使用指令級(jí)并行的優(yōu)化方案進(jìn)行了論述Vasily Volkov,Better Performance at Lower Occupancy, GTC 2010,UC Berkeley, September 22,2010,提出了可以在較低的占有率下進(jìn)行CUDA程序優(yōu)化,并給出具有優(yōu)化效果的程序樣例。Volkov在之后的另外兩篇文獻(xiàn) Vasily Volkov,Use registers and multiple outputs per thread on GPU,UC Berkeley,PMAAj 10, June30,2010 和 Vasily Volkov, Unrolling parallel loops, UC Berkeley, tutorial talk SCI I, November 14, 2011中對(duì)指令并行如何操作做了進(jìn)一步的解釋。但是, 這些文獻(xiàn)中都沒(méi)有對(duì)指令集并行優(yōu)化的場(chǎng)合和條件做出限定,這一技術(shù)與實(shí)際應(yīng)用仍有距離。本發(fā)明認(rèn)為指令級(jí)并行并不適合所有的代碼,并首次對(duì)指令并行使用的場(chǎng)合和條件做出嚴(yán)格限定。
上述這些公開(kāi)的優(yōu)化技術(shù)都只局限于CUDA程序優(yōu)化的幾個(gè)方面,不足以充分發(fā)揮GPU設(shè)備的運(yùn)算能力,實(shí)際達(dá)到的優(yōu)化效果也不夠完善;同時(shí),這些文獻(xiàn)或作者往往沒(méi)有給出技術(shù)的理論闡述,對(duì)優(yōu)化技術(shù)的使用場(chǎng)合和條件解釋的不清楚,因此很難達(dá)到實(shí)際可操作的標(biāo)準(zhǔn)。在實(shí)際編寫的大量CUDA程序中,性能的優(yōu)化工作往往是不夠的,要求更多的程序員可以快捷的掌握CUDA程序的編寫和優(yōu)化技術(shù)而不止是讓技術(shù)停留在研究層面。
因此,提出一套完整的實(shí)際可操作的,具有較強(qiáng)通用性和優(yōu)化效果的技術(shù)流程是本領(lǐng)域亟待解決的技術(shù)問(wèn)題。發(fā)明內(nèi)容
針對(duì)目前已公開(kāi)的優(yōu)化技術(shù)現(xiàn)狀,本發(fā)明提供了一種實(shí)際可操作的CUDA內(nèi)核程序性能優(yōu)化解決方案,從性能瓶頸的判定到優(yōu)化方法的選取,再到優(yōu)技術(shù)的具體實(shí)施給出詳細(xì)方案和步驟,為CUDA程序編寫和優(yōu)化提供依據(jù),幫助程序編寫者方便得找到CUDA程序中的性能瓶頸,并針對(duì)性能瓶頸做出高效有針對(duì)性的優(yōu)化,使得CUDA程序可以更大限度的發(fā)揮GPU設(shè)備的計(jì)算能力。
本發(fā)明所使用的CUDA架構(gòu)軟硬件特性資料主要引自本領(lǐng)域較權(quán)威的技術(shù)指南 《GPU高性能運(yùn)算之CUDA》(張舒,褚艷利等編著,中國(guó)水利水電出版社2009年)以及NVIDIA 公司提高的 CUDA C 編程手冊(cè)(NVIDIA. CUDA C Programming Guide. January 2012·)。目前市場(chǎng)上支持CUDA的GPU設(shè)備規(guī)格不盡相同,本發(fā)明以設(shè)備計(jì)算能力設(shè)備計(jì)算能力是衡量 GPU設(shè)備對(duì)CUDA支持能力的指標(biāo),較高級(jí)的版本會(huì)繼承發(fā)展較低級(jí)版本的全部特性并增添新的功能2. I的GF114子架構(gòu),GF114架構(gòu)是Fermi 2. O架構(gòu)的典型代表,該架構(gòu)的GPU是目前硬件市場(chǎng)的主流產(chǎn)品。
在本發(fā)明中以該設(shè)備為例具體說(shuō)明,并且盡可能的兼顧其它版本的計(jì)算能力。
本發(fā)明技術(shù)方案如下一種基于CUDA并行環(huán)境的GPU程序優(yōu)化方法,其步驟包括
I)根據(jù)CUDA上的程序分析工具對(duì)GPU程序進(jìn)行檢測(cè),得到程序需求占有率并判斷此時(shí)程序是否存在全局存儲(chǔ)器訪問(wèn)瓶頸,同時(shí)對(duì)所述全局存儲(chǔ)器訪問(wèn)瓶頸進(jìn)行消除,進(jìn)入步驟2);
2)根據(jù)共享存儲(chǔ)器中bank-conflicts訪問(wèn)沖突的數(shù)目判斷所述步驟I)的GPU程序中是否存在共享存儲(chǔ)器訪問(wèn)瓶頸,同時(shí)消除所述共享存儲(chǔ)器訪問(wèn)瓶頸和新生成的全局存儲(chǔ)器訪問(wèn)瓶頸,進(jìn)入步驟3);
3)使用CUDA的程序分析工具在所述步驟2)的GPU程序提取出性能參數(shù),綜合分析判斷是否存在流水線指令執(zhí)行依賴瓶頸并消除該指令流水線沖突,得到實(shí)際IPC可達(dá)到指令瓶頸IPC的GPU程序進(jìn)入步驟4);
4)在所述步驟3)中若GPU程序?qū)嶋HIPC達(dá)到指令瓶頸IPC,則進(jìn)行指令瓶頸優(yōu)化5處理;
5)重復(fù)遍歷以上步驟I) 一4),直至所述GPU程序不存在上述步驟2)-4)中的任意一項(xiàng)瓶頸并且程序性能提升滿足用戶需求,完成GPU程序優(yōu)化過(guò)程。
所述程序需求占有率¢1=^/48=0^/1^)=1=1748,其中Na為active warp數(shù)目,T為一次訪問(wèn)存儲(chǔ)延遲,NnZNi為訪問(wèn)存儲(chǔ)請(qǐng)求次數(shù)與指令數(shù)目之比。
所述全局存儲(chǔ)器訪問(wèn)瓶頸判斷方法是若實(shí)際占有率不能滿足需求占有率,則 GPU程序中存在全局存儲(chǔ)器訪問(wèn)瓶頸,所述實(shí)際占有率可以通過(guò)CUDA程序分析工具中 Parrallel Nsight 的 CUDA Memory Statistics 和 Instruction Statistics 讀出;所述共享存儲(chǔ)器中bank-conflicts訪問(wèn)沖突的數(shù)目通過(guò)Parrallel Nsight的CUDA Memory Statisti cs 中得出。
所述步驟I)重復(fù)直至實(shí)際占有率大于需求占有率,消除所述步驟I)中全局存儲(chǔ)器訪問(wèn)瓶頸的優(yōu)化方法包括提高線程級(jí)并行度、提高指令級(jí)并行度、全局存儲(chǔ)器轉(zhuǎn)存共享存儲(chǔ)器、全局存儲(chǔ)器訪存歸并。
所述步驟2)中共享存儲(chǔ)器訪問(wèn)瓶頸消除方法為改進(jìn)共享存儲(chǔ)器的訪問(wèn)任務(wù)分配解決bank-conflicts訪問(wèn)沖突和/或共享存儲(chǔ)器轉(zhuǎn)寄存器。如果存在共享存儲(chǔ)器 bank-conflict,優(yōu)先解決bank_confIict,如果每個(gè)線程處理彼此無(wú)關(guān)任務(wù),可以將訪問(wèn)不同bank的線程放在同一個(gè)warp內(nèi);當(dāng)不可避免的需要訪問(wèn)同一個(gè)bank內(nèi)部的數(shù)據(jù)時(shí),考慮這部分?jǐn)?shù)據(jù)的大小以及需要在線程間通信等因素,將這部分共享存儲(chǔ)器的數(shù)據(jù)轉(zhuǎn)存在寄存器中,可以考慮減少SM上線程的數(shù)目來(lái)獲取額外的寄存器資源。
所述流水線指令執(zhí)行依賴瓶頸優(yōu)化處理為提高線程級(jí)并行度和/或提高指令級(jí)并行度。
當(dāng)GPU中存在復(fù)雜的邏輯控制,每個(gè)線程的任務(wù)不盡相同,或者存在大量不可預(yù)測(cè)的分支跳轉(zhuǎn)時(shí),可以考慮增大SM的占有率,利用更多的線程級(jí)并行來(lái)掩蓋指令流水線延遲;
當(dāng)GPU程序出現(xiàn)重復(fù)大量無(wú)關(guān)的相同工作如對(duì)存儲(chǔ)器訪問(wèn)時(shí),考慮將多個(gè)無(wú)關(guān)的任務(wù)分配給單獨(dú)的線程來(lái)處理,利用更多的指令級(jí)并行解決依賴沖突。
所述指令瓶頸優(yōu)化處理為如果程序中存在影響warp分支的分支跳轉(zhuǎn),優(yōu)先將這部分工作移到同一個(gè)warp或者相鄰的線程中,或者高吞吐量指令替換低吞吐量指令和/或減少指令分支。
所述步驟3)中流水線指令執(zhí)行依賴瓶頸從GPU程序中Parrallel Nsight分析工具的 Issue Stalls Tab 得到,基于 Warp Issue Efficiency 餅狀圖中 eligible warp 的數(shù)目和 / 或 Issue Stall Reasons 餅狀圖中 Execution Dependency 所占的比例。
對(duì)部分程序所述全局存儲(chǔ)器訪問(wèn)瓶頸的判斷方法可采用存儲(chǔ)器訪問(wèn)替換的方法: 保留在全局存儲(chǔ)器訪問(wèn)時(shí)使用的索引計(jì)算,通過(guò)改變?nèi)执鎯?chǔ)器訪問(wèn),觀測(cè)程序執(zhí)行時(shí)間發(fā)生的變化。
所述改進(jìn)共享存儲(chǔ)器的訪問(wèn)任務(wù)時(shí)將共享存儲(chǔ)器的維度定義為warp數(shù)目加一, 并按照線程所在warp中的ID來(lái)訪問(wèn)共享存儲(chǔ)器。
本發(fā)明的有益效果
本發(fā)明在現(xiàn)有文獻(xiàn)的基礎(chǔ)上,改進(jìn)和發(fā)展了諸多CUDA內(nèi)核優(yōu)化技術(shù),明確定義了內(nèi)核的性能瓶頸,并為每個(gè)性能瓶頸提出實(shí)際可操作的判定標(biāo)準(zhǔn),利用方便的性能分析工具得到性能指標(biāo),輔助瓶頸判定,并提出了新的對(duì)于諸多優(yōu)化技術(shù)的使用條件,在上述內(nèi)容的基礎(chǔ)上完成優(yōu)化流程的設(shè)計(jì)。為CUDA程序編寫和優(yōu)化提供依據(jù),以盡量小的代價(jià)獲取更高的設(shè)備性能。
圖I是本發(fā)明基于CUDA并行架構(gòu)的GPU程序優(yōu)化方法針對(duì)不同瓶頸采用相應(yīng)的優(yōu)化方法。
圖2是本發(fā)明基于CUDA并行架構(gòu)的GPU程序優(yōu)化方法中一實(shí)施例的優(yōu)化流程圖。
具體實(shí)施方式
發(fā)明原理
CUDA并行程序的性能依賴于多種因素,各自的因素都會(huì)使得程序的執(zhí)行時(shí)間存在一個(gè)特定的下限,而最終程序的執(zhí)行時(shí)間取決于下限中最低的一個(gè)。在已公開(kāi)的文獻(xiàn)中大都提及到了 CUDA程序的性能瓶頸或者性能優(yōu)化點(diǎn)。本發(fā)明仍然采用性能瓶頸的優(yōu)化模式, 為了達(dá)到優(yōu)化程序性能的目的,首先要為廣泛的程序性能瓶頸給出定義(本發(fā)明可能涉及與現(xiàn)有文獻(xiàn)中相同或類似的性能瓶頸,但定義與現(xiàn)有文獻(xiàn)給出的定義不完全相同)。
GPU設(shè)備的處理器在運(yùn)行過(guò)程中僅會(huì)處于兩種狀態(tài)執(zhí)行指令流水線和等待延遲,執(zhí)行指令使設(shè)備的計(jì)算資源得到了利用,而等待延遲則浪費(fèi)了設(shè)備的計(jì)算能力。本發(fā)明的優(yōu)化方法將主要的性能瓶頸按照優(yōu)先級(jí)(可參考NVIDIA. CUDA C Programming Guide. January 2012.和 Peng Wang. CUDA Optimization. In:NVIDIA GPU Technology Conference, 2010.等)分為以下四類全局存儲(chǔ)器訪問(wèn)瓶頸、共享存儲(chǔ)器訪問(wèn)瓶頸、指令執(zhí)行依賴瓶頸和指令瓶頸。雖然除此之外仍存在其它因素,諸如指令獲取延遲(指令的獲取實(shí)際上是和全局存儲(chǔ)器訪問(wèn)一樣耗時(shí)的操作,但由于指令緩存的存在(具體指令緩存可參見(jiàn)文獻(xiàn)張舒,褚艷利.GPU高性能計(jì)算之CUDA[M].中國(guó)水利水電出版社,2009.),在性能優(yōu)化中這一部分的因素常常被忽略、線程同步延遲(線程同步或線程通信是CUDA程序中常見(jiàn)的操作,但針對(duì)不同的程序線程同步的影響差別很大,同時(shí)由于線程同步是保證程序正確性所必不可少的,CUDA程序優(yōu)化將其作為次要因素)等影響程序性能,但這四個(gè)因素是影響最大的。以下列出各種程序瓶頸產(chǎn)生的原因。
I.全局存儲(chǔ)器(全局存儲(chǔ)器是在顯存上最大塊的存儲(chǔ)器,通常在內(nèi)核程序運(yùn)行前動(dòng)態(tài)分配。在整個(gè)內(nèi)核程序運(yùn)行周期中,全局存儲(chǔ)器可以被GPU上的所有線程所共享)訪問(wèn)瓶頸全局存儲(chǔ)器訪問(wèn)瓶頸產(chǎn)生的原因是存在全局存儲(chǔ)器訪問(wèn)延遲。內(nèi)存和CPU之間幾乎不存在訪問(wèn)延遲,而顯存則位于顯卡之外,使得訪問(wèn)全局存儲(chǔ)器的代價(jià)非常高,達(dá)到GPU 執(zhí)行單元單個(gè)指令周期的幾百倍。這里的全局存儲(chǔ)器指的是一類存儲(chǔ)單元,它們都位于顯存上。原始數(shù)據(jù)從主機(jī)端內(nèi)存?zhèn)鬏數(shù)斤@存中供GPU處理器使用,訪問(wèn)全局存儲(chǔ)器必不可少, 如果大量的指令等待全局存儲(chǔ)器訪存,那么昂貴的訪問(wèn)延遲使得設(shè)備的計(jì)算能力大大降低;另一方面,對(duì)GPU顯存的訪問(wèn)是以段(在設(shè)備計(jì)算能力為I. 2的GPU設(shè)備上,段的長(zhǎng)度為 128Bytes)為基本單位的,同一時(shí)間對(duì)位于同一段內(nèi)的多個(gè)訪問(wèn)都會(huì)被轉(zhuǎn)化為對(duì)顯存的一次訪問(wèn)(具體可參見(jiàn)本發(fā)明內(nèi)容優(yōu)化技術(shù)2全局存儲(chǔ)器歸并訪問(wèn))。
2.共享存儲(chǔ)器訪問(wèn)瓶頸共享存儲(chǔ)器訪問(wèn)瓶頸是因?yàn)楣蚕泶鎯?chǔ)器的存在訪問(wèn)沖突。共享存儲(chǔ)器位于GPU處理器內(nèi)部,主要用于線程之間通信和作為顯存緩存。每個(gè)流多處理器(SM, Stream Multiprocessor)中的共享存儲(chǔ)器被組織為大小相等的存儲(chǔ)器模塊,稱為bank,每個(gè)bank的寬度固定為32/64bit,相鄰的bank由16/32 (計(jì)算能力2. O以上的 bank寬度提升為63bit,bank控制器的數(shù)目提升到32個(gè))個(gè)不同的存儲(chǔ)器控制器來(lái)管理。 由于每個(gè)bank控制器每個(gè)時(shí)鐘僅能做一次存儲(chǔ)訪問(wèn),當(dāng)多個(gè)線程訪問(wèn)的區(qū)域位于同一個(gè) bank時(shí)便會(huì)產(chǎn)生bank沖突(bank-conflict)。盡管共享存儲(chǔ)器的訪問(wèn)延遲可以忽略不計(jì), 但bank-conflict訪問(wèn)沖突導(dǎo)致了共享存儲(chǔ)器訪問(wèn)可能存在幾個(gè)時(shí)鐘周期的延遲。當(dāng)遇到 bank conflict時(shí)GPU分多周期完成該warp的訪存,延遲的長(zhǎng)度取決于bank conflict的嚴(yán)重程度,即如果32個(gè)線程都訪問(wèn)同一個(gè)bank,那么只有等待32個(gè)周期后,這條對(duì)共享存儲(chǔ)器的訪存操作才可以順利完成。warp是GPU執(zhí)行CUDA程序時(shí)基本的任務(wù)調(diào)度單位,目前CUDA的warp的大小為32個(gè)線程,處在同一個(gè)warp內(nèi)的線程,以不同數(shù)據(jù)資源執(zhí)行相同的指令,warp 是一種 SIMT 執(zhí)行模型(SIMT, Single Instruction Multiple Thread,是對(duì) SIMD, Single Instruction Multiple Data 的一種改進(jìn))
3.指令執(zhí)行依賴瓶頸這里的指令流水線沖突主要指的是對(duì)寄存器數(shù)據(jù)的讀寫訪問(wèn)沖突(指令依賴沖突具體可參見(jiàn)文獻(xiàn)張舒,褚艷利.GPU高性能計(jì)算之CUDA[M].中國(guó)水利水電出版社,2009.),當(dāng)一條指令執(zhí)行依賴于上一條或者臨近指令的計(jì)算結(jié)果時(shí),這條指令就會(huì)被流處理器延后,當(dāng)這樣的沖突頻繁發(fā)生時(shí),完整的處理器流水線會(huì)損失很多計(jì)算時(shí)間,從而降低程序的性能。
4.指令瓶頸當(dāng)程序大多時(shí)間處在執(zhí)行指令流水線的狀態(tài)時(shí),GPU設(shè)備往往可以獲得很高的指令吞吐量,流處理器的計(jì)算能力得到較為充分的利用,將這一類程序歸為指令瓶頸。指令瓶頸是程序優(yōu)化的較理想狀態(tài)但這并不意味著程序的運(yùn)行時(shí)間不能進(jìn)一步減少。由于指令瓶頸要求指令流水線高負(fù)荷工作,只有當(dāng)上述3中瓶頸都被解決時(shí),指令瓶頸的優(yōu)化才有意義。
優(yōu)化技術(shù)
這里列舉主要的優(yōu)化技術(shù)(本領(lǐng)域技術(shù)人員能夠明白在實(shí)際編程時(shí)的優(yōu)化技術(shù)存在許多非常小的技巧,本發(fā)明在這里只列出公認(rèn)的最有效技術(shù),更多的技術(shù)細(xì)節(jié)可參見(jiàn)對(duì)應(yīng)優(yōu)化技術(shù)后的參考文獻(xiàn)等),這些優(yōu)化技術(shù)針對(duì)特定的性能瓶頸都可以實(shí)現(xiàn)有效的性能提升。
全局存儲(chǔ)器轉(zhuǎn)共享存儲(chǔ)器
對(duì)于頻繁訪問(wèn)的全局存儲(chǔ)器上的數(shù)據(jù),將其拷貝到共享存儲(chǔ)器,然后再?gòu)墓蚕泶鎯?chǔ)器上讀取來(lái)使用,由于共享存儲(chǔ)器的大小有限同時(shí)也需要作為線程通信的媒介,將訪問(wèn)最為頻繁的顯存數(shù)據(jù)轉(zhuǎn)存在共享存儲(chǔ)器里。(NVIDIA. CUDA C Programming Guide. January 2012.、Peng Wang. CUDA Optimization.1n:NVIDIA GPU Technology Conference, 2010.、張舒,褚艷利.GPU高性能計(jì)算之CUDA [Μ].中國(guó)水利水電出版社,2009.)
全局存儲(chǔ)器訪存歸并
對(duì)于同一個(gè)warp內(nèi)部的線程如果訪問(wèn)相同的段區(qū)域,訪存請(qǐng)求可以在一次訪存中完成。相反,跨越更多的區(qū)域段就需要更多次的全局存儲(chǔ)器訪問(wèn),使得訪問(wèn)代價(jià)提高,這就要求全局存儲(chǔ)器的訪問(wèn)盡量歸并。(NVIDIA. CUDA C Programming Guide. January 2012·、Peng Wang. CUDA Optimization.1n:NVIDIA GPU Technology Conference, 2010.、張舒,褚艷利.GPU高性能計(jì)算之CUDA [M].中國(guó)水利水電出版社,2009.)
解決共享存儲(chǔ)器bank conflict
組織線程塊(Thread block) (Thread block是GPU的任務(wù)分發(fā)與資源分配單位,同一個(gè)block內(nèi)部的線程可以利用共享存儲(chǔ)器實(shí)現(xiàn)通信,是線程間協(xié)作的主要對(duì)象)內(nèi)部的warp使得共享存儲(chǔ)器的訪問(wèn)分屬于不同的bank,這要求程序編寫者合理分配GPU線程任務(wù)。一個(gè)有效的手段是在定義共享存儲(chǔ)器時(shí),將一維的大小設(shè)為線程塊寬度加一,這樣在處理按行數(shù)據(jù)訪問(wèn)和按列數(shù)據(jù)訪問(wèn)時(shí)都不會(huì)引發(fā)bank conflict。(Peng Wang. CUDA Optimization.1n:NVIDIA GPU Technology Conference, 2010.、張舒,褚艷利· GPU 高性能計(jì)算之CUDA [M],中國(guó)水利水電出版社,2009.)
籲共享存儲(chǔ)器轉(zhuǎn)存寄存器
對(duì)于頻繁訪問(wèn)的共享存儲(chǔ)器上的數(shù)據(jù),將其拷貝到寄存器上,然后再?gòu)募拇嫫魃献x取來(lái)使用,使用寄存器充當(dāng)共享存儲(chǔ)器的的功能。這種方法主要解決共享存儲(chǔ)器不夠用或者共享存儲(chǔ)器訪問(wèn)bank-conflict不可避免的情況。技術(shù)實(shí)現(xiàn)的難點(diǎn)在于合理的給每個(gè)線程分配寄存器和計(jì)算任務(wù),使得寄存器充當(dāng)共享存儲(chǔ)器共享和緩存的作用,因?yàn)閱蝹€(gè)SM上寄存器數(shù)目有限,有時(shí)候?yàn)榱俗寙蝹€(gè)線程獲得更多的寄存器,必須降低同一個(gè) SM 上活躍 warp 的數(shù)目。(Peng Wang. CUDA Optimization.1n:NVIDIA GPU Technology Conference, 2010.、張舒,褚艷利.GPU高性能計(jì)算之CUDA [M] ·中國(guó)水利水電出版社, 2009.)
提高線程級(jí)并行
提高一個(gè)SM上的active warp (active warp是指處在活動(dòng)狀態(tài)的warp,這一類的warp所需要的執(zhí)行環(huán)境 在硬件上均已準(zhǔn)備好。由于硬件資源的限定,同一時(shí)間GPU上不可能為所有warp的線程提供執(zhí)行環(huán)境(包括指令、寄存器、存儲(chǔ)器等資源),active warp數(shù)目極大的影響線程執(zhí)行的并行度)數(shù)目。線程級(jí)并行度是NIVIDA在CUDA架構(gòu)提出來(lái)時(shí)極力提倡的并行方式。由于單個(gè)SM對(duì)在其上運(yùn)行的線程塊數(shù)目和資源占用有嚴(yán)格的限定, 為了達(dá)到更多的active warp數(shù)目,需要控制好每個(gè)線程塊的大小以及線程塊使用的資源數(shù)目,綜合SM上的設(shè)備資源上限從而達(dá)到更高的SM設(shè)備占有率(SM設(shè)備占有率又被成為占有率,是在單一 SM上衡量active warp數(shù)目的指標(biāo)),提聞線程級(jí)并行度。SM的理論占有率由設(shè)備計(jì)算能力和線程塊的資源分配決定,而實(shí)際取得的占有率也會(huì)受線程塊數(shù)目和線程長(zhǎng)度等因素影響。(具體可參考 NVIDIA. CUDA C Programming Guide. January 2012·、 Peng Wang. CUDA Optimization.1n:NVIDIA GPU Technology Conference, 2OlO.、張舒,褚艷利.GPU高性能計(jì)算之CUDA [Μ].中國(guó)水利水電出版社,2009.)
提高指令級(jí)并行
指令級(jí)并行是在線程內(nèi)部提高程序執(zhí)行并行度的方法。由于CUDA設(shè)備支持小范圍的指令亂序執(zhí)行(可參考張舒,褚艷利.GPU高性能計(jì)算之CUDA[M].中國(guó)水利水電出版社,2009.),可以將一個(gè)線程內(nèi)部循環(huán)執(zhí)行部分自動(dòng)或者手動(dòng)的方式展開(kāi),通過(guò)添加新的臨時(shí)變量來(lái)減少指令之間的數(shù)據(jù)相關(guān)性,從而為設(shè)備進(jìn)行指令級(jí)并行提供支持。指令級(jí)并行度不能直觀的反映在SM占有率上,但它可以更直接為SM提供足夠的eligible warp (eligible warp是在單個(gè)指令周期內(nèi)處于可以發(fā)射狀態(tài)的線程warp,相較于active warp更直接的反映出設(shè)備計(jì)算單元的利用情況。eligible warp是順利獲取計(jì)算資源的那部分 active warp,通常eligible warp的數(shù)目會(huì)小于active warp的數(shù)目),因此對(duì)于特定的 CUDA設(shè)備可以顯著提高指令的吞吐量。但由于GPU對(duì)指令亂序執(zhí)行的支持僅限于局部指令,同時(shí)分支跳轉(zhuǎn)語(yǔ)句會(huì)大大降低這種并行效率,因此提高指令級(jí)并行對(duì)提高程序并行度的作用也是有限的。(具體可參考 V. Volkov. Better performance at lower occupancy.1n:NVIDIA GPU Technology Conference, 2010.和V. Volkov. Use registers and multiple outputs per thread on GPU, UC Berkeley, PMAA’ 10, June 30,2010)
高吞吐量指令替換低吞吐量指令
對(duì)于可以實(shí)現(xiàn)相同功能的不同代碼,優(yōu)先選擇指令吞吐量較大的指令,由于程序中任何指令的執(zhí)行都需要特定的流水線周期,利用流水線周期較短的指令可以顯著的提高指令吞吐量,從而在較短時(shí)間內(nèi)完成功能。(可參考NVIDIA. CUDA C Programming Guide.January2012. > Peng Wang. CUDA Optimization.1n:NVIDIA GPU Technology Conference, 2010.、張舒,褚艷利.GPU高性能計(jì)算之CUDA [M] ·中國(guó)水利水電出版社, 2009.)
減少指令分支
指令分支會(huì)造成處在同一個(gè)warp內(nèi)部的線程分為兩個(gè)甚至更多的warp分開(kāi)執(zhí)行,指令的執(zhí)行數(shù)目得到倍數(shù)上的增長(zhǎng),同時(shí)也會(huì)破壞原有的指令緩存,增加指令獲取的代價(jià)。因此盡可能將同一個(gè)操作的線程放在同一個(gè)warp中,保證程序中出現(xiàn)較少的分支,從而降低指令的數(shù)目,減少運(yùn)行時(shí)間。(具體步驟可參考NVIDIA. CUDA C Programming Guide.January2012. > Peng Wang. CUDA Optimization.1n:NVIDIA GPU Technology Conference, 2010.、張舒,褚艷利.GPU高性能計(jì)算之CUDA [M] ·中國(guó)水利水電出版社, 2009.)
下面結(jié)合附圖對(duì)本發(fā)明實(shí)施例進(jìn)行詳細(xì)的說(shuō)明
如圖1所示是CUDA并行架構(gòu)的GPU程序優(yōu)化方法針對(duì)不同瓶頸采用相應(yīng)的優(yōu)化方法,具體流程如下
瓶頸判定方法
如圖1所示,是CUDA程序的性能瓶頸判定是程序優(yōu)化的關(guān)鍵步驟,在實(shí)際操作是必須要有明確的性能指標(biāo)和判定標(biāo)準(zhǔn),本發(fā)明使用Parrallel Nsight (NVIDIA公司發(fā)布的整合在Visual Studio中的CUDA程序調(diào)試與分析工具)工具獲得某些GPU程序的性能指標(biāo),并采用分析和判定方法對(duì)GPU程序進(jìn)行瓶頸判定,以下所使用到的性能指標(biāo)都可通過(guò) Parrallel Nsight 工具測(cè)量得到。(Parrallel Nsight 的使用方法參見(jiàn) NVIDIA. Parrallel Nsight User Guide. 2012.)
全局存儲(chǔ)器訪問(wèn)瓶頸的判定方法
全局存儲(chǔ)器訪問(wèn)瓶頸的統(tǒng)一判定標(biāo)準(zhǔn)是SM需求占有率和SM實(shí)際占有率的比較。 實(shí)際占有率可以通過(guò)CUDA程序分析工具中直接讀出;需求占有率需要通過(guò)性能指標(biāo)計(jì)算得出,這里給出一個(gè)實(shí)際可行計(jì)算公式
需求占有率估計(jì)值a=Na/48= (Nm/Ni) *T/48
其中Na為active warp數(shù)目,T為一次訪存的延遲(T的具體數(shù)字范圍從400到800 不等),Nm/Ni為訪存的請(qǐng)求次數(shù)與指令數(shù)目之比,Nm和Ni指標(biāo)可以從Parrallel Nsight的CUDA Instruction Statistics和Memory Statistics結(jié)果中查出。這里需要說(shuō)明的是, 上述的計(jì)算方法僅是從整體上給指令執(zhí)行和數(shù)據(jù)訪問(wèn)的比例做了粗略限定,即使需求占有率估計(jì)值小于實(shí)際占有率也不能完全保證指令執(zhí)行時(shí)各個(gè)時(shí)段都不存在訪問(wèn)延遲等待。在實(shí)際優(yōu)化過(guò)程中,上述公式計(jì)算的需求占有率應(yīng)當(dāng)盡量小于實(shí)際的占有率。
除了上述粗略的判定標(biāo)準(zhǔn)外,對(duì)于部分程序可以采用存儲(chǔ)器訪問(wèn)替換的方式判定是否存在全局存儲(chǔ)器訪問(wèn)瓶頸。具體做法是保留在全局存儲(chǔ)器訪問(wèn)時(shí)使用的索引計(jì)算(不能因改變?cè)L問(wèn)方式而缺失計(jì)算量),將對(duì)全局存儲(chǔ)器的訪問(wèn)變?yōu)槌?shù)計(jì)算,如下所示
權(quán)利要求
1.一種基于CUDA并行環(huán)境的GPU程序優(yōu)化方法,其步驟包括 1)根據(jù)CUDA上的程序分析工具對(duì)GPU程序進(jìn)行檢測(cè),得到程序需求占有率并判斷此時(shí)程序是否存在全局存儲(chǔ)器訪問(wèn)瓶頸,同時(shí)對(duì)所述全局存儲(chǔ)器訪問(wèn)瓶頸進(jìn)行消除,進(jìn)入步驟2); 2)根據(jù)共享存儲(chǔ)器中bank-conflicts訪問(wèn)沖突的數(shù)目判斷所述步驟I)的GPU程序中是否存在共享存儲(chǔ)器訪問(wèn)瓶頸,同時(shí)消除所述共享存儲(chǔ)器訪問(wèn)瓶頸和新生成的全局存儲(chǔ)器訪問(wèn)瓶頸,進(jìn)入步驟3); 3)使用CUDA的程序分析工具在所述步驟2)的GPU程序提取出性能參數(shù),判斷是否存在流水線指令執(zhí)行依賴瓶頸并消除該指令流水線沖突,得到實(shí)際IPC可達(dá)到指令瓶頸IPC的GPU程序進(jìn)入步驟4); 4)在所述步驟3)中若GPU程序?qū)嶋HIPC達(dá)到指令瓶頸IPC,則進(jìn)行指令瓶頸優(yōu)化處理; 5)重復(fù)遍歷以上步驟I)一4),直至所述GPU程序不存在上述步驟2)-4)中的任意一項(xiàng)瓶頸,完成GPU程序優(yōu)化。
2.如權(quán)利要求I所述的基于CUDA并行環(huán)境的GPU程序優(yōu)化方法,其特征在于,所述程序需求占有率a =Na/48= (NnZNi) *T/48,其中Na為active warp數(shù)目,T為一次訪問(wèn)存儲(chǔ)延遲,NnZNi為訪問(wèn)存儲(chǔ)請(qǐng)求次數(shù)與指令數(shù)目之比。
3.如權(quán)利要求I所述的基于CUDA并行環(huán)境的GPU程序優(yōu)化方法,其特征在于,所述全局存儲(chǔ)器訪問(wèn)瓶頸判斷方法是若實(shí)際占有率不能滿足需求占有率,則GPU程序中存在全局存儲(chǔ)器訪問(wèn)瓶頸,所述實(shí)際占有率可以通過(guò)CUDA程序分析工具中ParrallelNsight 的 CUDA Memory Statistics 和 Instruction Statistics 讀出;所述共享存儲(chǔ)器中bank-conflicts訪問(wèn)沖突的數(shù)目通過(guò)Parrallel Nsight 的 CUDA Memory Statistics 中得出。
4.如權(quán)利要求I所述的基于CUDA并行環(huán)境的GPU程序優(yōu)化方法,其特征在于,所述步驟I)重復(fù)直至實(shí)際占有率大于需求占有率,消除所述步驟I)中全局存儲(chǔ)器訪問(wèn)瓶頸的優(yōu)化方法包括提高線程級(jí)并行度、提高指令級(jí)并行度、全局存儲(chǔ)器轉(zhuǎn)存共享存儲(chǔ)器、全局存儲(chǔ)器訪存歸并。
5.如權(quán)利要求I所述的基于CUDA并行環(huán)境的GPU程序優(yōu)化方法,其特征在于,所述步驟2)中共享存儲(chǔ)器訪問(wèn)瓶頸消除方法為改進(jìn)共享存儲(chǔ)器的訪問(wèn)任務(wù)分配解決bank-conflicts訪問(wèn)沖突和/或共享存儲(chǔ)器轉(zhuǎn)寄存器。
6.如權(quán)利要求I所述的基于CUDA并行環(huán)境的GPU程序優(yōu)化方法,其特征在于,所述流水線指令執(zhí)行依賴瓶頸的優(yōu)化處理方法為提高線程級(jí)并行度和/或提高指令級(jí)并行度; 當(dāng)GPU中存在復(fù)雜的邏輯控制,每個(gè)線程的任務(wù)不盡相同,或者存在大量不可預(yù)測(cè)的分支跳轉(zhuǎn)時(shí),可以考慮通過(guò)增大SM的占有率,利用更多的線程級(jí)并行來(lái)掩蓋指令流水線延遲; 當(dāng)GPU程序出現(xiàn)重復(fù)大量無(wú)關(guān)的相同工作如對(duì)存儲(chǔ)器訪問(wèn)時(shí),考慮通過(guò)將多個(gè)無(wú)關(guān)的任務(wù)分配給單獨(dú)的線程來(lái)處理的方法解決依賴沖突。
7.如權(quán)利要求I所述的基于CUDA并行環(huán)境的GPU程序優(yōu)化方法,其特征在于,所述指令瓶頸優(yōu)化處理為如果程序中存在影響warp分支的分支跳轉(zhuǎn),優(yōu)先將這部分工作移到同一個(gè)warp或者相鄰的線程中,或者高吞吐量指令替換低吞吐量指令和/或減少指令分支。
8.如權(quán)利要求I所述的基于CUDA并行環(huán)境的GPU程序優(yōu)化方法,其特征在于,所述步驟3)中流水線指令執(zhí)行依賴瓶頸從GPU程序中Parrallel Nsight分析工具的IssueStalls Tab 得到,基于 Warp Issue Efficiency 餅狀圖中 eligible warp 的數(shù)目和 / 或Issue Stall Reasons 餅狀圖中 Execution Dependency 所占的比例。
9.如權(quán)利要求I或3所述的基于CUDA并行環(huán)境的GPU程序優(yōu)化方法,其特征在于,對(duì)部分程序所述全局存儲(chǔ)器訪問(wèn)瓶頸的判斷方法可采用存儲(chǔ)器訪問(wèn)替換的方法保留在全局存儲(chǔ)器訪問(wèn)時(shí)使用的索引計(jì)算,通過(guò)改變?nèi)执鎯?chǔ)器訪問(wèn),觀測(cè)程序執(zhí)行時(shí)間發(fā)生的變化。
10.如權(quán)利要求I或5所述的基于CUDA并行環(huán)境的GPU程序優(yōu)化方法,其特征在于,所述改進(jìn)共享存儲(chǔ)器的訪問(wèn)任務(wù)時(shí)將共享存儲(chǔ)器的維度定義為warp數(shù)目加一,并按照線程所在warp中的ID來(lái)訪問(wèn)共享存儲(chǔ)器。
全文摘要
本發(fā)明涉及一種基于CUDA并行環(huán)境的GPU并行程序優(yōu)化方法,定義了GPU程序內(nèi)核的性能瓶頸,根據(jù)級(jí)別包括全局儲(chǔ)存器訪問(wèn)延遲、共享存儲(chǔ)器訪問(wèn)沖突、指令流水線沖突、指令瓶頸。并為每個(gè)性能瓶頸提出實(shí)際可操作的判定標(biāo)準(zhǔn)和瓶頸優(yōu)化解決方法全局儲(chǔ)存器訪問(wèn)延遲優(yōu)化方法轉(zhuǎn)存共享存儲(chǔ)器、訪問(wèn)歸并、提高線程級(jí)并行度、提高指令級(jí)并行度;共享存儲(chǔ)器訪問(wèn)沖突和指令流水線沖突優(yōu)化方法解決bank conflict,轉(zhuǎn)存寄存器、提高線程級(jí)并行度、提高指令級(jí)并行度;指令瓶頸指令替換和減少分支。本發(fā)明為CUDA程序編寫和優(yōu)化提供依據(jù),幫助程序編寫者方便得找到CUDA程序中的性能瓶頸,并針對(duì)性能瓶頸做出高效有針對(duì)性的優(yōu)化,使得CUDA程序可以更大限度的發(fā)揮GPU設(shè)備的計(jì)算能力。
文檔編號(hào)G06F9/38GK102981807SQ201210444220
公開(kāi)日2013年3月20日 申請(qǐng)日期2012年11月8日 優(yōu)先權(quán)日2012年11月8日
發(fā)明者孟洋, 李勝, 汪國(guó)平 申請(qǐng)人:北京大學(xué)