技术开发 频道

GPU 的硬體架構

  【IT168 文档】這裡我們會簡單介紹,NVIDIA 目前支援 CUDA 的 GPU,其在執行 CUDA 程式的部份(基本上就是其 shader 單元)的架構。這裡的資料是綜合 NVIDIA 所公布的資訊,以及 NVIDIA 在各個研討會、學校課程等所提供的資料,因此有可能會有不正確的地方。主要的資料來源包括 NVIDIA 的 CUDA Programming Guide 1.1、NVIDIA 在 Supercomputing '07 介紹 CUDA 的 session,以及 UIUC 的 CUDA 課程。

  GPU 的基本介紹

  目前 NVIDIA 推出的顯示晶片,支援 CUDA 的是 G80 系列的顯示晶片。其中 G80 顯示晶片支援 CUDA 1.0 版,而 G84、G86、G92、G94、G96 則支援 CUDA 1.1 版。基本上,除了最早的 GeForce 8800 Ultra/GTX 及 320MB/640MB 版本的 GeForce 8800GTS、Tesla 等顯示卡是 CUDA 1.0 版之外,其它 GeForce 8 系列及 9 系列顯示卡都支援 CUDA 1.1。詳細情形可以參考 CUDA Programming Guide 1.1 的 Appendix A。

  所有目前支援 CUDA 的 NVIDIA 顯示晶片,其 shader 部份都是由多個 multiprocessors 組成。每個 multiprocessor 裡包含了八個 stream processors,其組成是四個四個一組,也就是說實際上可以看成是有兩組 4D 的 SIMD 處理器。此外,每個 multiprocessor 還具有 8192 個暫存器,16KB 的 share memory,以及 texture cache 和 constant cache。大致上如下圖所示:

  詳細的 multiprocessor 資訊,都可以透過 CUDA 的 cudaGetDeviceProperties() 函式或 cuDeviceGetProperties() 函式取得。不過,目前還沒有辦法直接取得一個顯示晶片中有多少 multiprocessor 的資訊。

  在 CUDA 中,大部份基本的運算動作,都可以由 stream processor 進行。每個 stream processor 都包含一個 FMA(fused-multiply-add)單元,可以進行一個乘法和一個加法。比較複雜的運算則會需要比較長的時間。

  執行過程

  在執行 CUDA 程式的時候,每個 stream processor 就是對應一個 thread。每個 multiprocessor 則對應一個 block。從之前的文章中,可以注意到一個 block 經常有很多個 thread(例如 256 個),遠超過一個 multiprocessor 所有的 stream processor 數目。這又是怎麼回事呢?

  實際上,雖然一個 multiprocessor 只有八個 stream processor,但是由於 stream processor 進行各種運算都有 latency,更不用提記憶體存取的 latency,因此 CUDA 在執行程式的時候,是以 warp 為單位。目前的 CUDA 裝置,一個 warp 裡面有 32 個 threads,分成兩組 16 threads 的 half-warp。由於 stream processor 的運算至少有 4 cycles 的 latency,因此對一個 4D 的 stream processors 來說,一次至少執行 16 個 threads(即 half-warp)才能有效隱藏各種運算的 latency。

  由於 multiprocessor 中並沒有太多別的記憶體,因此每個 thread 的狀態都是直接保存在 multiprocessor 的暫存器中。所以,如果一個 multiprocessor 同時有愈多的 thread 要執行,就會需要愈多的暫存器空間。例如,假設一個 block 裡面有 256 個 threads,每個 thread 用到 20 個暫存器,那麼總共就需要 256x20 = 5,120 個暫存器才能保存每個 thread 的狀態。目前 CUDA 裝置中每個 multiprocessor 有 8,192 個暫存器,因此,如果每個 thread 使用到 16 個暫存器,那就表示一個 multiprocessor 同時最多只能維持 512 個 thread 的執行。如果同時進行的 thread 數目超過這個數字,那麼就會需要把一部份的資料儲存在顯示記憶體中,就會降低執行的效率了。

0
相关文章