2013-07-11 35 views
26

我最近開始瞭解NVCC如何爲不同的計算架構編譯CUDA設備代碼。在Nvidia的NVCC編譯器中使用多個「拱形」標誌的目的是什麼?

根據我的理解,使用NVCC的-gencode選項時,「arch」是程序員應用程序所需的最小計算體系結構,也是NVCC的JIT編譯器將編譯PTX代碼的最小設備計算體系結構。

我也明白,-gencode的「code」參數是NVCC完全編譯應用程序的計算體系結構,因此不需要JIT編譯。

各種CUDA項目生成文件的檢查後,我發現下面經常發生:

-gencode arch=compute_20,code=sm_20 
-gencode arch=compute_20,code=sm_21 
-gencode arch=compute_21,code=sm_21 

和一些閱讀後,我發現,多種設備的架構可以在一個單一的二進制文件編譯爲 - 中這種情況sm_20,sm_21。

我的問題是爲什麼有這麼多的拱/碼對是必要的?上面所用的「拱」的所有值都是?

是什麼,之間的區別說:

-arch compute_20 
-code sm_20 
-code sm_21 

是在自動選擇了「拱」領域最早的虛擬架構,或者是有一些其他的模糊的行爲呢?

是否有其他編譯和運行時行爲,我應該知道?

我已閱讀手冊,http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-compilation,我仍然不清楚編譯或運行時會發生什麼情況。

乾杯,

詹姆斯。

回答

31

粗略地講,代碼編譯流程是這樣的:

CUDA C/C++設備代碼源 - > PTX - > SASS

虛擬架構(例如compute_20,無論是通過-arch compute...指定)確定將生成什麼類型​​的PTX代碼。附加開關(例如-code sm_21)確定將生成什麼類型​​的SASS碼。 SASS實際上是GPU(機器語言)的可執行目標代碼。一個可執行文件可以包含SASS和/或PTX的多個版本,並且有一個運行時加載器機制,可以根據實際使用的GPU選擇合適的版本。

正如您指出的那樣,GPU操作的便捷功能之一就是JIT編譯。 JIT編譯將由GPU驅動程序完成(不需要安裝CUDA工具包),只要合適的PTX代碼可用,但合適的SASS代碼不可用。包含多個虛擬體系結構(即PTX的多個版本)的一個優勢是,您可以與更廣泛的目標GPU設備執行兼容性(儘管某些設備可能會觸發JIT編譯以創建必要的SASS )。包含多個「真實GPU目標」的一個優點(即,多個SASS版本)是,當其中一個目標設備存在時,您可以避免JIT編譯步驟。

如果指定了一組錯誤的選項,可以創建一個不會在特定GPU上正確運行的可執行文件。

指定很多這些選項的一個可能的缺點是代碼大小膨脹。另一個可能的缺點是編譯時間,在指定更多選項時通常會更長。

也可以創建不包含PTX的可改變字符,這可能會讓試圖隱藏IP的用戶感興趣。

創建適用於JIT的PTX應該由specifying a virtual architecturecode交換機完成。

+1

道歉這麼晚纔回復,感謝你的。我理解PTX爲許多真正的架構進行JIT編譯的目的,但是是否有必要包含所有這些較舊的PTX架構,或僅包含最低規格的PTX?例如,如果我希望代碼能夠在儘可能多的GPU上運行,那麼我會包含-arch compute_11,12 13 ... 30,35還是僅包含-arch compute_11? 最好, 詹姆斯。 –

+3

您可以指定'-arch compute_11',並且您將生成cc 1.1 PTX代碼。現在和未來的所有GPU應該能夠從此版PTX到某些有用的機器代碼(除cc 1.0設備之外)進行JIT編譯。但是,通過指定其他PTX版本,您可以通過添加一個「更新的」PTX,爲更好地利用新架構提供機會,從而使您的代碼在cc3.0設備上運行得更快,如果您還指定了'compute_30'。這是代碼大小/編譯時間和最佳性能之間的折衷。你的旅費可能會改變。 –

+0

現在都清楚,很好的答案。謝謝你的時間! –

相關問題