本發明是一種GPU L1 Cache處訪存序列的仿真生成與排序方法,屬于計算機體系結構和并行計算領域。
背景技術:
近十年來,GPU從專用圖形處理器逐漸發展成通用計算平臺,憑借其強大的并行計算能力和功耗控制能力,GPU通用計算在科學計算領域得到了廣泛的應用和關注。由于GPU芯片將大部分面積都分配給計算單元,僅分配少量芯片面積給Cache和控制單元,大量GPU應用程序的性能受限于GPU的訪存速度,而非計算能力。對于GPU訪存限制型應用程序,Cache使用效率對程序整體性能影響顯著,優化Cache使用效率以提高整體性能是一種重要的手段。為了幫助程序開發者理解GPU Cache行為特征,選擇恰當的Cache優化方法,準確性高、速度快、功能全的GPU Cache缺失分析工具就顯得的尤為重要。
現有的GPU Cache缺失分析工具依據其采集信息的原理可以分為三類:基于硬件計數器、基于時鐘精確模擬器和基于訪存序列分析。基于硬件記數器的工具運行速度最快,但它依賴于實體的GPU硬件,并且提供的信息十分有限,不具備擴展性;基于時鐘精確模擬器的方法提供的信息量大,抓取信息最為方便,但運行的時間開銷過于龐大,并且其支持的GPU微結構體系十分有限;基于訪存序列分析的方法結合了前兩種方法的長處:不僅提供足夠的信息量,具備多種架構適應性,并且將時間開銷控制在可以接受的范圍內。
在GPU體系結構中,L1 Cache被SM中同時運行的幾十甚至幾百個線程共享,給基于訪存序列的GPU L1 Cache缺失行為的分析造成困難。我們不僅需要獲取SM中各線程有序的訪存序列,還必須獲取來自不同線程的訪存請求到達L1 Cache的先后順序。然而,目前尚無有效方法準確地從硬件計數器,或是仿真環境中獲取以上信息。
技術實現要素:
發明目的:針對上述現有技術存在的問題和不足,本發明的目的是提出一種GPU L1 Cache處訪存序列的仿真生成與排序方法,準確提供各線程訪存請求到達L1 Cache的先后順序以及各線程有序的訪存序列,為基于訪存序列的GPU L1 Cache缺失分析和優化提供基礎,充分發揮GPU L1 Cache和整個訪存系統的性能。
技術方案:為實現上述發明目的,本發明采用的技術方案為GPU L1 Cache處訪存序列的仿真生成與排序方法,該訪存序列是指一個線程從開始執行到結束執行對全局存儲按順序發生的所有訪存請求的記錄,每一次訪存請求的記錄包含以下信息:
線程id:發出該訪存請求的線程id;
PC值:發出該訪存請求的訪存指令的程序計數器值;
訪存地址:訪存請求的數據所在地址;
數據寬度:訪存請求的數據寬度,以字節為單位;
數據依賴性標志:取值為0或1,表示下一條訪存請求之前,當前訪存請求的數據是否會被其它指令使用到;
其中,數據依賴標志與PC值匹配,同一個PC值下所有訪存請求具有相同的數據依賴標志;
具體包括以下步驟:
1a)訪存序列生成:使用GPU功能模擬器提供的接口,編寫序列生成器,在模擬器上運行GPU程序時,序列生成器自動抓取各線程發出的訪存請求信息,并存儲為各線程初始的訪存序列;
1b)線程調度:將一定數量的相鄰的線程劃分到同一個線程束中,根據應用程序線程塊的維度設置,將一定數量相鄰的線程束劃分到同一個線程塊中,再根據每個流多處理器上能夠同時運行的最大線程塊數量限制,依次將各個線程塊分配到流多處理器;將位于同一流多處理器中的各線程初始的訪存序列劃分到一個任務組中;
1c)訪存合并:在同一個線程束中,執行同一條訪存指令的多個線程發出的所有訪存請求中,根據訪存請求的數據寬度和各訪存請求的訪存地址分布進行訪存合并,生成一個新的訪存請求,并相應獲得該線程束內合并后的有序的訪存序列;
1d)訪存排序,在每個任務組內,按照來自不同線程的訪存請求到達L1Cache的先后順序,將任務組內各線程有序的訪存序列合并成一個該任務組總的有序訪存序列。
進一步的,在步驟1c)中,根據訪存請求的數據寬度進行訪存合并,若當訪存請求4個字節的數據時,在整個線程束32個線程范圍內進行訪存合并;若當訪存請求8個字節或16個字節的數據時,則分別以半個線程束即16個線程或四分之一個線程束即8個線程范圍內進行訪存合并,并以此類推。
進一步的,在步驟1c)中,根據各線程訪存請求的訪存地址分布進行訪存合并,其條件為:緩存行地址相同的訪存請求才能夠進行合并,緩存行地址=訪存地址/緩存行大小。
進一步的,所述步驟1c)所述的訪存合并包括下面4個子步驟:
4a)創建一個用于存儲合并后的有序訪存請求集合,并初始化該集合為空;創建一個待合并訪存請求集合,將同一個線程束內執行同一條訪存指令的多個線程發出的所有訪存請求存入其中,完成初始化;
4b)從待合并訪存請求集合中取出一個訪存請求,并由該訪存請求的訪存地址計算訪存請求的緩存行地址;
4c)判斷步驟4a)創建的合并后有序訪存請求集合中是否存在與當前訪存請求的緩存行地址相同的訪存請求;若不存在,則把當前訪存請求加入合并后有序訪存請求集合中,并將其從待合并訪存請求集合中剔除;若存在,則將合并后有序訪存請求集合中同緩存行地址的原有訪存請求以及當前訪存請求合并,生成新的訪存請求,獲得對應的訪存序列信息如下:取與合并前一致的PC值和數據依賴性標志,取被合并兩個訪存請求中較小的線程id和對應的訪存地址,取能夠覆蓋被合并兩個訪存請求所有訪問數據的最小數據寬度,后將該被合并的當前訪存請求從待合并訪存請求集合中剔除;
4d)如待合并訪存請求集合中所有訪存請求全部處理完畢,則合并后有序訪存請求集合中的訪存序列即為合并后的訪存請求所組成的有序訪存序列,如待合并訪存請求集合中的訪存請求未全部處理完畢,回到步驟4b)執行。
進一步的,步驟1d)中,根據線程調度原則,通過循環體對同一任務組內多個線程束的訪存請求到達L1Cache的先后順序排序,所述循環體算法為:某一個線程執行完一條指令后,直接跳轉到由線程調度原則決定的下一個可用的線程取下一個訪存請求,輪轉到最后一個線程后即跳轉回第一個線程,形成循環。
進一步的,步驟1d)所述的訪存排序包括下面6個子步驟:
6a)考慮到線程阻塞會影響到訪存請求到達L1Cache順序,創建一個線程阻塞標志數組,記錄每一個線程id的阻塞標志,初始化所有線程id為未被阻塞狀態,設阻塞標志為0;考慮到訪存排序受線程阻塞和指令阻塞影響,創建一個延時未結束訪存請求集合,初始化為空;創建一個用于存放由排序后訪存記錄所組成的訪存序列集合,初始化為空;
6b)根據線程調度原則,從一個任務組內多個線程中挑選出一個阻塞標志為0的線程,并取出該線程訪存序列中的一個訪存請求;
6c)檢查延時未結束訪存請求集合,如果為空,跳過6c)步驟,直接進入步驟6d)執行;否則,將非空延時未結束訪存請求集合中所有訪存請求的訪存延時減1,并剔除該集合中所有延時已減至0的訪存請求,同時更新數組中這些訪存請求對應線程的阻塞標志為0;
6d)判斷存取單元是否忙碌,即,如果延時未結束訪存請求集合中訪存請求數量達到GPU存取單元容量上限,則存取單元忙碌,回到步驟6c)執行;否則,存取單元不忙碌,進入步驟6e)執行;
6e)將步驟6b)中取出的訪存請求添加到排序后的訪存序列集合;將該訪存請求加入延時未結束訪存請求集合中,依據訪存延時分布規律為其生成一個初始的訪存延時值;對于該訪存請求,若其數據依賴性標志為1,就將數組中當前訪存請求所處線程的阻塞標志設為1,反之,其數據依賴性標志為0,就將數組中當前訪存請求所處線程的阻塞標志設為0;
6f)若任務組內所有線程的訪存請求處理完畢,則得到該任務組內排序后的訪存序列集合;否則回到步驟6b)執行。
進一步的,步驟6e)中,訪存延時分布規律采用均值為0、標準差為σ的正態分布模型N(0,σ)產生隨機數來模型訪存延時。
進一步的,步驟6e)中所述的訪存延時分布,任何訪存延時分布都適用。
進一步的,步驟6b)中所述的線程調度原則,任何調度原則都適用。
有益效果:本發明所述的GPU L1 Cache處訪存序列的仿真生成與排序方法,使用GPU功能模擬器生成GPU應用程序各線程初始的訪存序列,在充分解析GPU訪存系統微結構特征后,對該訪存序列采取線程調度、訪存合并和訪存排序三大步驟,最終得到GPU應用程序在GPU L1 Cache處的仿真訪存序列。該訪存序列便于進行GPU L1 Cache缺失行為特征分析。本發明所述的GPU L1 Cache處訪存序列的仿真生成與排序方法考慮了線程調度算法、訪存延時造成的線程阻塞和存取單元忙碌造成的指令阻塞三個因素對線程執行進度的影響,因此,本發明輸出的GPU L1 Cache處訪存序列接近GPU硬件中的真實情況,準確度高。
附圖說明
附圖用來提供對本發明的進一步理解,并且構成說明書的一部分,與本發明的實施例一起用于解釋本發明,并不構成對本發明的限制。在附圖中:
圖1為本發明的實施例的總體工作流程;
圖2為本發明的實施例中各線程有序的訪存序列仿真生成流程;
圖3為本發明的實施例中訪存合并的工作流程;
圖4為本發明的實施例中使用的循環體線程調度算法;
圖5為本發明的實施例中訪存序列排序的工作流程。
具體實施方式
下面結合附圖及在英偉達GPU下的實施例對本文發明進一步詳細說明。
如圖1所示,本發明實施例包含訪存序列生成、線程調度、訪存合并和訪存排序共四個步驟。
步驟一,訪存序列生成:訪存序列是指一個程序從開始執行到結束執行對全局存儲的所有訪問記錄,訪存記錄以訪存指令執行的先后排序。每條訪存記錄包含了一個線程一次訪存請求的相關信息,包括發起訪存請求的線程id、訪存指令的PC值、訪存地址、訪存請求的數據寬度和數據依賴性標志。序列生成器生成的各線程有序的訪存序列中,同一個線程訪存序列中訪存請求出現的先后位置與訪存請求到達L1Cache的先后順序相一致,但是來自不同線程的訪存請求到達L1Cache的先后順序不確定。
步驟二,線程調度:線程調度具體分為三個層次:首先,將所有相鄰的32個線程劃分到同一個線程束warp中,以英偉達GPU為例,每個線程束warp包含32個線程;然后,根據應用程序線程塊Thread Block的維度設置,將一定數量相鄰的線程束Warp劃分到同一個線程塊Thread Block中;最后,再根據每個流多處理器SM上能夠同時運行的最大線程塊Thread Block數量限制,依次將各個線程分配到多個流多處理器上。具體的計算公式如下所示:其中,thread_id表示線程編號,warp_id表示線程束編號,block_id表示線程塊編號,sm_id表示流多處理器編號,num_warps_per_block表示單個線程塊Thread BLock內最大線程束Warp數量,num_blocks_per_sm表示單個流多處理器SM上能夠同時運行的最大線程塊Thread Block數量。其中,warp_id,block_id,以及sm_id的計算公式如下:
warp_id=thread_id/32
block_id=warp_id/num_warps_per_block
sm_id=block_id%num_blocks_per_sm
步驟三,訪存合并:在一個線程束Warp內執行同一條訪存指令的多個線程(通常是32個線程)發出的多個訪存請求中,根據訪存請求的數據寬度和各線程訪存請求的地址分布不同進行訪存合并。數據寬度方面,當訪存請求4個字節的數據時,在整個線程束32個線程范圍內進行訪存合并;當訪存請求8個字節或16個字節的數據時,則分別以半個線程束即16個線程或四分之一個線程束即8個線程范圍內進行訪存合并。線程訪存地址分布方面,只有分配到同一緩存行,即緩存行地址相同的訪存請求才能夠進行合并,緩存行地址不同的訪存請求無法合并。
步驟四,訪存排序:本發明的實施例中,通過一個循環體實現對同一任務組內多個線程束warp的訪存序列按照訪存請求抵達GPU L1 Cache的先后次序排序。循環體每執行一次,從各線程有序的訪存序列中挑選出下一個要處理的訪存請求,將該訪存請求插入到排好序的訪存序列中。各線程有序的訪存序列中所有訪存請求處理完畢后,就得到GPU L1 Cache處總的有序訪存序列。
圖2為本發明的實施例中訪存序列生成器的執行流程。GPU功能模擬器使用的是由美國佐治亞理工學院計算機架構和系統實驗室開發的一款用于英偉達GPU的模擬器Ocelot。Ocelot模擬器提供了專門用于訪存序列生成的接口。具體的執行流程如下:首先,GPU應用程序開始執行之前,在序列生成器內注冊生成器,通知Ocelot模擬器在特定事件觸發后調用序列生成器內提供的事件處理函數;然后,開始執行GPU應用程序,其中的串行代碼仍然在宿主CPU處理器上運行,但并行代碼不是運行于GPU硬件,而是模擬執行于Ocelot模擬器。Ocelot模擬器每執行一條PTX匯編指令,都會觸發一次事件,序列生成器內的事件處理函數負責采集各次訪存信息,并將生成的訪存序列在恰當的時間寫入指定的文件中;最后,Ocelot模擬執行完所有并行Kernel,將執行權交回給串行程序,并最終結束整個訪存序列生成流程。
圖3為本發明的實施例中訪存合并方法執行流程,具體分為4個步驟。一、創建一個空的集合,用于存儲合并后的訪存請求;二、從合并前的多個訪存請求中取出一個訪存請求,并計算它請求的緩存行地址;三、判斷步驟一創建的集合中是否存在一個訪存請求,它請求的緩存行地址與當前訪存請求相同。如果不存在,則把當前訪存請求存入集合中;如果存在,則合并原有訪存請求和當前訪存請求生成新的訪存請求。四、如果合并前的訪存請求全部處理完畢,則生成了合并后的訪存請求集合,結束該執行流程,否則回到以上步驟二執行。
圖4展示了本發明的實施例中訪存排序所使用的循環體Round Robin線程調度算法。循環體Round Robin算法的基本原則為:某一個線程執行完一條指令后,立即依次跳轉到下一個處于就緒狀態的線程,而不會在一個線程上連續停留執行多條指令。基于循環體Round Robin算法從訪存序列中挑選訪存請求的具體方法是:從某線程取走一個訪存請求后,立即跳轉到下一個可用的線程取下一個訪存請求,而不會在同一個線程的訪存序列中停留或連續取兩個訪存請求,輪轉到最后一個線程后即跳轉回第一個線程,形成循環。以上過程如圖4所示。基于循環體Round Robin線程調度算法保證了各個線程的訪存請求被選取的進度基本是一致的,并與英偉達GPU硬件架構中的線程束調度算法相一致。
圖5為本發明的實施例中訪存序列排序的工作流程圖。除了循環體Round Robin線程調度算法外,本發明還考慮了訪存延時造成的線程阻塞和存取單元忙碌造成的指令阻塞的影響。
訪存延時造成的線程阻塞方面,英偉達GPU中,當一個線程發射出一條訪存指令后,在訪存數據返回之前,后續的指令可能會處于等待訪存數據的狀態而無法繼續執行,因而后續的訪存指令也無法順利發出。后續的指令能否繼續發射取決于后續指令的是否依賴于當前訪存所請求的數據,如果有依賴,則后續指令會阻塞;如果沒有依賴,則后續指令就不會阻塞。在本發明的實施例中,一個線程的某條訪存請求被取出后,即根據訪存序列中的線程阻塞信息選擇性地將線程標記為阻塞狀態,在阻塞狀態下,該線程的后續訪存請求不能被取出。直到前一條訪存請求的數據返回,阻塞狀態解除,該線程后續訪存請求才能繼續被取出。
存取單元造成的指令阻塞方面,英偉達GPU中,使用MSHR寄存器記錄正在缺失中的訪存請求信息,記錄的信息包括失效地址和訪存請求的來源信息。當MSHR寄存器溢出(MSHR寄存器被占滿)時,新的訪存請求將無法成功發出,相應的指令發射失敗;發射失敗的指令將反復嘗試發射,直到MSHR寄存器出現空閑。在本發明的實施例中,當檢查到存取單元忙碌,即MSHR寄存器溢出時,會暫停對訪存請求的排序,一直等到某些訪存請求延時結束,數據末返回的訪存請求數量小于MSHR寄存器總個數,即MSHR寄存器出現空閑,再繼續訪存請求的排序,如圖5所示。
由于各次訪存的準確延時無法確定,本發明的實施例采用正態分布模型產生隨機數來模型訪存延時。具體的計算公式如下所示:其中,N(0,σ)表示均值為0、標準差為σ的正態分布,abs是求絕對值函數,M是延時最小值,σ和M的值依據實驗數據估計;T是最終分配的“訪存延時”,T并不是以時間為單位的實際延時值,而是訪存數據到達處理器之前還可以發射其它線程的訪存個數。
T=M+abs(N(0,σ))
最后應說明的是:以上所述僅為本發明的優選實施例而已,并不用于限制本發明,盡管參照前述實施例對本發明進行了詳細的說明,對于本領域的技術人員來說,其依然可以對前述各實施例所記載的技術方案進行修改,或者對其中部分技術特征進行等同替換。凡在本發明的精神和原則之內,所作的任何修改、等同替換、改進等,均應包含在本發明的保護范圍之內。