CUDA C编程接口技术分析
CUDA C編程接口技術分析
編程接口
CUDA C為熟悉C編程語言的用戶提供了一個簡單的路徑,可以方便地編寫程序供設備執行。
它由C語言的最小擴展集和運行庫組成。
核心語言擴展已經引入:cuda c programming guide。它們允許程序員將內核定義為C函數,并在每次調用該函數時使用一些新語法來指定網格和塊維度。任何包含這些擴展名的源文件都必須用nvcc編譯。
在編譯工作流中引入了運行時。它提供在主機上執行的C函數,用于分配和解除分配設備內存、在主機內存和設備內存之間傳輸數據、管理具有多個設備的系統等。運行時的完整描述可在CUDA參考手冊中找到。
運行時構建在較低級別的C API(CUDA驅動程序API)之上,應用程序也可以訪問該API。驅動程序API通過公開較低級別的概念(如CUDA上下文——設備的主機進程模擬)和CUDA模塊——設備的動態加載庫模擬,提供了額外的控制級別。大多數應用程序不使用驅動程序API,因為它們不需要這種額外的控制級別,并且在使用運行時,上下文和模塊管理是隱式的,從而產生更簡潔的代碼。驅動程序API在驅動程序API中介紹,并在參考手冊中詳細描述。
1.?使用NVCC編譯
內核可以使用CUDA指令集體系結構(稱為PTX)編寫,PTX參考手冊中對此進行了描述。然而,使用高級編程語言(如C)通常更有效。在這兩種情況下,內核必須由nvcc編譯成二進制代碼才能在設備上執行。
nvcc是一個編譯器驅動程序,它簡化了編譯C或PTX代碼的過程:它提供簡單而熟悉的命令行選項,并通過調用實現不同編譯階段的工具集合來執行這些選項。本節概述了nvcc工作流和命令選項。完整的描述可以在nvcc用戶手冊中找到。
1.1.?編制工作流程
1.1.1.離線編譯
用nvcc編譯的源文件可以包括主機代碼(即,在主機上執行的代碼)和設備代碼(即,在設備上執行的代碼)的混合。nvcc的基本工作流程是將設備代碼與主機代碼分離,然后:
·將設備代碼編譯為匯編形式(PTX代碼)和/或二進制形式(cubin對象),
·修改宿主代碼,用必要的CUDA C運行時函數調用替換內核中引入的語法(并在執行配置中詳細描述),以便從PTX代碼和/或cubin對象加載和啟動每個編譯的內核。
修改后的主機代碼輸出為C代碼,該代碼將留在使用另一個工具編譯時使用,或者通過讓nvcc在最后一個編譯階段調用主機編譯器直接作為目標代碼輸出。
應用程序可以:
·鏈接到已編譯的主機代碼(這是最常見的情況),
·或者忽略修改后的主機代碼(如果有的話),并使用CUDA驅動程序API(請參閱驅動程序API)來加載和執行PTX代碼或cubin對象。
1.1.2.?及時編譯
應用程序在運行時加載的任何PTX代碼都由設備驅動程序進一步編譯為二進制代碼。這稱為即時編譯。即時編譯增加了應用程序加載時間,但允許應用程序從每個新設備驅動程序帶來的任何新編譯器改進中獲益。這也是應用程序在編譯應用程序時不存在的設備上運行的唯一方法,如應用程序兼容性中所述。
當設備驅動程序及時為某個應用程序編譯一些PTX代碼時,它會自動緩存生成的二進制代碼的副本,以避免在隨后的應用程序調用中重復編譯。當設備驅動程序升級時,緩存(稱為計算緩存)會自動失效,因此應用程序可以從設備驅動程序中內置的新實時編譯器的改進中獲益。
環境變量可用于控制CUDA環境變量中描述的實時編譯。
1.2.二進制兼容性
二進制代碼是特定于體系結構的。cubin對象是使用指定目標體系結構的編譯器選項-code生成的:例如,使用-code=sm_35編譯會為具有計算能力3.5的設備生成二進制代碼。二進制兼容性保證從一個小版本到下一個小版本,但不是從一個小版本到上一個小版本或跨主要版本。換句話說,為計算能力X.y生成的cubin對象將只在計算能力X.z的設備上執行,其中z≥y。
1.3.?PTX兼容性【PTX兼容性】
某些PTX指令僅在具有更高計算能力的設備上受支持。例如,Warp Shuffle函數僅在計算能力為3.0及以上的設備上受支持。-arch編譯器選項指定在編譯C到PTX代碼時假設的計算能力。例如,包含warp shuffle的代碼必須使用-arch=compute_30(或更高版本)編譯。
為某些特定計算能力生成的PTX代碼始終可以編譯為具有更大或同等計算能力的二進制代碼。請注意,從早期PTX版本編譯的二進制文件可能無法使用某些硬件功能。例如,從為計算能力6.0(Pascal)生成的PTX編譯的計算能力7.0(Volta)的二進制目標設備將不會使用張量核心指令,因為這些指令在Pascal上不可用。因此,最終的二進制文件的性能可能比使用最新版本的PTX生成的二進制文件的性能差。
1.4.?應用程序兼容性
要在具有特定計算能力的設備上執行代碼,應用程序必須加載與此計算能力兼容的二進制或PTX代碼,如二進制兼容性和PTX兼容性中所述。特別是,為了能夠在具有更高計算能力的未來架構上執行代碼(還不能生成二進制代碼),應用程序必須加載PTXcode,該PTXcode將為這些設備及時編譯(請參閱及時編譯)。
哪個PTX和二進制代碼嵌入到CUDA C應用程序中,由-arch和-code編譯器選項或-gencode編譯器選項控制,如nvcc用戶手冊中所述。例如,
嵌入與計算能力3.5和5.0(第一和第二gencode選項)兼容的二進制代碼,以及與計算能力6.0(第三gencodepoption)兼容的PTX和二進制代碼。
生成宿主代碼是為了在運行時自動選擇要加載和執行的最合適的代碼,在上面的示例中,將是:
·3.5計算能力為3.5和3.7的設備的二進制代碼,
·5.0計算能力為5.0和5.2的設備的二進制代碼,
·6.0計算能力為6.0和6.1的設備的二進制代碼,
·PTX代碼,在運行時為具有計算能力7.0及更高版本的設備編譯為二進制代碼。
x.cu可以有一個優化的代碼路徑,使用warp shuffle操作,例如,只有計算能力3.0及更高的設備才支持這種操作。可以使用“CUDA ARCH”宏根據計算能力區分不同的代碼路徑。它只為設備代碼定義。例如,當使用-arch=compute_35編譯時,__CUDA_ARCH_等于350。
使用驅動程序API的應用程序必須編譯代碼以分離文件,并在運行時顯式加載和執行最合適的文件。
Volta架構引入了獨立的線程調度,它改變了GPU上線程的調度方式。對于依賴于以前架構中SIMT調度的特定行為的代碼,獨立的線程調度可能會改變參與線程的集合,從而導致錯誤的結果。為了幫助遷移,同時實現獨立線程調度中詳述的糾正操作,Volta開發人員可以選擇使用編譯器選項-arch=compute_60 -code=sm_70來執行Pascal的線程調度。
nvcc用戶手冊列出了-arch、-code和-gencode編譯器選項的各種簡寫。例如,
-arch=sm_35 is a shorthand for -arch=compute_35-code=compute_35, sm_35 (which is the same as -gencodearch=compute_35, code=‘compute_35,sm_35’).
1.5、C/C++兼容性
編譯器的前端編譯器根據C++語法規則處理CUDA源文件。但是,對于C/C++語言描述的設備代碼,只支持C++的一個子集。
1.6.?64位兼容性
64位版本的nvcc以64位模式編譯設備代碼(即指針為64位)。只有在64位模式下編譯的主機代碼才支持在64位模式下編譯的設備代碼。
類似地,32位版本的nvcc以32位模式編譯設備代碼,而32位模式編譯的設備代碼僅支持以32位模式編譯的主機代碼。
32位版本的nvcc還可以使用-m64編譯器選項以64位模式編譯設備代碼。
64位版本的nvcc可以使用-m32編譯器選項以32位模式編譯設備代碼。
總結
以上是生活随笔為你收集整理的CUDA C编程接口技术分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何选择视觉CV光源颜色
- 下一篇: 电脑识别指令和代码的原理