CUDA儲存器組織
最靠近流處理器的是暫存器檔案(register file),每個暫存器檔案是32bit。對執行緒來說,暫存器都是私有的,不允許其它執行緒染指。由於更靠近流處理器,暫存器具有最快的速度,GT200的每個SM擁有64KB的暫存器檔案(Register Files),故一個塊內最多可分配16K個暫存器,而G80中每個SM只有32KB,故一個塊最多可分配8K個暫存器。最新加入的64bit資料型別(雙精度浮點和64位整數型)將佔用兩個相鄰的暫存器單元。CUDA的執行環境能夠動態的為執行緒塊分配暫存器,而每個執行緒塊中的執行緒佔用的暫存器大小則是靜態分配的,線上程塊壽命期間都不會更改,因此一個執行緒佔用的暫存器數目是它在執行時佔用的最大數目。如果暫存器被消耗完,資料將被儲存在本地儲存器(local memory)。對每個執行緒來說,本地儲存器也是私有的,但是本地儲存器是視訊記憶體中的一個分割槽,速度很慢,而且使用本地儲存器過多的話,程式也會終止,因此,程式設計時要儘量保證不能將資料放到本地儲存器中,這可以通過修改塊大小,使用共享儲存器等方法來解決。
共享儲存器是可以被同一塊中的所有執行緒訪問的可讀寫儲存器,它的生存期就是塊的生命期。在沒有衝突的情況下,訪問共享儲存器幾乎與訪問暫存器一樣快,是實現執行緒間通訊的最好方法。共享儲存器可以實現許多不同的功能,如用於儲存共用的計數器或者塊內的公用結果(例如reduction)。在同一個塊內,所有的執行緒都能夠讀寫共享儲存器中的資料,相比於AMD的顯示卡來說,共享儲存器是NVIDIA顯示卡的一項特色。一般而言,在kernel執行時,要先將資料從全域性儲存器寫入共享儲存器;計算完成後要將共享儲存器中的結果轉存入全域性儲存器。
Tesla的每個SM擁有16KB共享儲存器,用於同一個執行緒塊內的執行緒間通訊。為了使一個half-warp內的執行緒能夠在一個核心週期中並行訪問,共享儲存器被組織成16個bank,每個bank擁有32bit的寬度,故每個bank可儲存256個整形或單精度浮點數,或者說目前的bank組織成了256行16列的矩陣。如果一個half-warp中有一部分執行緒訪問屬於同一bank的資料,則會產生bank conflict,降低訪存效率,在衝突最嚴重的情況下,速度會比全域性視訊記憶體還慢,但是如果half-warp的執行緒訪問同一地址的時候,會產生一次廣播,其速度反而沒有下降。在不發生bank conflict時,訪問共享儲存器的速度與暫存器相同。在不同的塊之間,共享儲存器是毫不相關的。 Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE
在實現中,GPU要把視訊記憶體中的資料寫到共享儲存器中,必須先把資料寫到暫存器裡,再轉移到共享儲存器中,在程式設計時,這是隱式實現的。所以如果沒有塊內的資料共享千萬不能用共享儲存器,否則會降低速度。但是如果由於暫存器使用過量,那麼我們可以使用共享儲存器來當暫存器使用,此時比純使用暫存器慢一點,但是是值得的。
Tesla能夠在共享儲存器內進行高速的原子操作。這裡的原子操作是指保證每個執行緒能夠獨佔的訪問儲存器,即只有當一個執行緒完成對儲存器的某個位置的操作以後,其他執行緒才能訪問這一位置。G80只支援對global memory的原子操作。訪問global memory需要很長的訪存延遲(長達數百個時鐘週期),效能很低。在GT200及以後的GPU上,可以支援對shared memory中的原子操作指令(其中包括CAS指令,並且支援64位)。但是,CUDA並不提供對浮點數的原子操作(只有一個賦值的浮點原子指令),而在科學計算中,浮點數的使用遠比整數要多,而且在Fermi的特性列表中,也沒有看到加入浮點原子指令的資訊,這不能不說是一個遺憾。 Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE
除此以外,多處理器上,還有兩種只讀的儲存器:常數儲存器(constant memory)和紋理儲存器(texture memory),它們是利用GPU用於圖形計算的專用單元實現的。常數儲存器空間較小(只有64KB),屬於片外儲存器,其速度比shared要慢,但是它具有快取,並且無須考慮衝突問題,主要用來加速對常數的訪問。
從物理上說,紋理儲存器不是儲存器,它只是利用了紋理快取而已。紋理快取與CPU的快取有很大的不同。首先,CPU的快取往往是一維的,因為大多數的架構中的儲存器地址是線性的。當訪問一個只有4-8Byte的資料字時,會取出一個快取單元中所有的64B資料。根據區域性性原理,CPU處理的資料往往有很強的時空相關性,因此多取出的相鄰的資料極有可能會被用到。CPU處理的資料只有一維,因而其快取也只是在一個維度上是連續的;GPU需要處理的紋理則是連續的二維影像,因此紋理快取也必須是在兩個維度上連續分佈的。典型的儲存器控制器會將二維的紋理儲存器空間對映為一維。其次,紋理快取是隻讀的,也不滿足資料一致性。當紋理被修改以後,必須更新整個紋理快取,而不是紋理快取中被修改的一小部分。第三,紋理快取的主要功能是為了節省頻寬和功耗,而CPU的快取則是為了實現較低的延遲。第四,紋理可以實現對資料的特殊處理,比如怎樣處理越界資料,自動實現插值等。
最後是全域性儲存器(global memory),使用的是普通的視訊記憶體。整個網格中的任意執行緒都能讀寫全域性儲存器的任意位置。目前對Global memory的訪問沒有快取,因此視訊記憶體的效能對GPU至關重要。為了能夠高效的訪問視訊記憶體,讀取和儲存必須對齊,寬度為4Byte。如果沒有正確的對齊,讀寫將被編譯器拆分為多次操作,極大的影響效率。此外,多個half-warp的讀寫操作如果能夠滿足合併訪問(coalesced access),那麼多次訪存操作會被合併成一次完成,從而提高訪問效率。
G80的合併訪存條件十分嚴格。首先,訪存的開始地址必須對齊:16x32bit的合併必須對齊到64Byte(即訪存起始地址必須是64Byte的整數倍);16x64bit的合併訪存起始必須對齊到128Byte;16x128bit合併訪存的起始地址必須對齊到128Byte,但是必須橫跨連續的兩個128Byte區域。其次,只有當第K個執行緒訪問的就是第K個資料字時,才能實現合併訪問,否則half warp中的16個訪存指令就會被髮射成16次單獨的訪存。
GT200不僅放寬了合併訪問條件,而且還能支援對8bit和16bit資料字的合併訪問(分別使用32Byte和64Byte傳輸)。在一次合併傳輸的資料中,並不要求執行緒編號和訪問的資料字編號相同。其次,當訪問128Byte資料時如果地址沒有對齊到128Byte,在G80中會產生16次訪存指令發射,而在GT200中只會產生兩次合併訪存。而且,這兩次合併訪存並不是兩次128Byte的。例如,一次128Byte訪存中有32Byte在一個區域中,另外一個區域中有96Byte,那麼只會產生一次32Byte合併訪存(對有32Byte資料的區域)和一次128Byte(對有96Byte資料的區域)。 Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE
除了device端儲存器外,還有存在於host端的儲存器,即記憶體。在CUDA中,主機端記憶體分為兩種:Pageable host memory和Page-locked host memory,其中Page-locked host memory保證位在於實體記憶體中,並且能夠通過DMA加速與顯示卡的通訊,提高資料傳輸速度,但是如果主機的記憶體不夠用的話,會減弱系統的效能,但是一般不會出現這種情況。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23057064/viewspace-626987/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 儲存器、I/O組織、微處理器
- [譯]在CUDA C/C++中使用共享儲存器C++
- 【計組】3.7 虛擬儲存器
- 新技術讓3D列印生物組織更方便儲存ZKT3D
- 儲存器
- 主儲存器
- 外部儲存器
- 傳統儲存器和新興儲存器應用
- 組裝一臺私人云儲存主機配置推薦 家庭NAS雲端儲存伺服器搭建伺服器
- 給自己組一個本地儲存
- 20932虛擬儲存器
- 只讀儲存器ROM
- 儲存器的知識
- 高速率儲存器UFS
- 嵌入式中常見的儲存器總結(一)儲存器分類
- 資料儲存-領存高速海量資料記錄儲存模組產品介紹
- Spark 儲存模組原始碼學習Spark原始碼
- [計組 notes] Chapter 3 儲存系統APT
- 塊儲存 檔案儲存 物件儲存物件
- 領存工業級三防資料儲存SSD-3U Open VPX 儲存模組
- 領存ASAAC儲存控制模組產品規格書
- SRAM是什麼儲存器
- Flash儲存器的故障特徵特徵
- 常見儲存器分類
- 瀏覽器儲存的方法瀏覽器
- 資料儲存(1):從資料儲存看人類文明-資料儲存器發展歷程
- LlamaFS自組織檔案管理器
- 儲存—物件儲存_Minio物件
- 如何延長儲存伺服器上資料的儲存時間?伺服器
- 座席組織
- 儲存器的層次結構
- 伺服器資料的儲存伺服器
- 第5章 虛擬儲存器
- 非易失性儲存器EEPROM
- 雲原生儲存編排器Rook
- 行式儲存 列式儲存
- 利用Dectorator分模組儲存Vuex狀態(上)Vue
- 利用Dectorator分模組儲存Vuex狀態(下)Vue
- 深入剖析 RocketMQ 原始碼 - 訊息儲存模組MQ原始碼