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