Programming Interface
編程模型中介紹了核心語言擴(kuò)展。它們允許程序員將內(nèi)核定義為c++函數(shù),并在每次調(diào)用函數(shù)時(shí)使用一些新的語法來指定網(wǎng)格和塊維度。在c++語言擴(kuò)展中可以找到對所有擴(kuò)展的完整描述。任何包含這些擴(kuò)展名的源文件都必須用nvcc編譯。
CUDA runtime中介紹了運(yùn)行時(shí)。它提供在主機(jī)上執(zhí)行的C和c++函數(shù),用于分配和釋放設(shè)備內(nèi)存,在主機(jī)內(nèi)存和設(shè)備內(nèi)存之間傳輸數(shù)據(jù),管理具有多個(gè)設(shè)備的系統(tǒng),等等。
運(yùn)行時(shí)構(gòu)建在較低級的C API (CUDA驅(qū)動(dòng)程序API)之上,該API也可由應(yīng)用程序訪問。驅(qū)動(dòng)程序API通過公開諸如 CUDA contexts (the analogue of host processes for the device)和 CUDA modules (the analogue of dynamically loaded libraries for the device.)等較低級別的概念提供了額外的控制級別。大多數(shù)應(yīng)用程序不使用驅(qū)動(dòng)程序API,因?yàn)樗鼈儾恍枰@種額外級別的控制,而且在使用運(yùn)行時(shí)時(shí),上下文和模塊管理是隱式的,因此代碼更簡潔。由于運(yùn)行時(shí)與驅(qū)動(dòng)程序API是互操作的,大多數(shù)需要一些驅(qū)動(dòng)程序API特性的應(yīng)用程序可以默認(rèn)使用運(yùn)行時(shí)API,并且只在需要的地方使用驅(qū)動(dòng)程序API。
Compilation with NVCC
內(nèi)核可以使用CUDA指令集體系結(jié)構(gòu)(稱為PTX)編寫。內(nèi)核必須被NVCC編譯成二進(jìn)制代碼才能在設(shè)備上執(zhí)行。
nvcc是一個(gè)編譯器驅(qū)動(dòng)程序,它簡化了編譯c++或PTX代碼的過程 :它提供了簡單而熟悉的命令行選項(xiàng),并通過調(diào)用實(shí)現(xiàn)不同編譯階段的工具集合來執(zhí)行它們。本節(jié)概述了nvcc工作流和命令選項(xiàng)。
Compilation Workflow
Offline Compilation
用nvcc編譯的源文件可以包括主機(jī)代碼(即在主機(jī)上執(zhí)行的代碼)和設(shè)備代碼(即在設(shè)備上執(zhí)行的代碼)的混合。nvcc的基本工作流程包括將設(shè)備代碼從主機(jī)代碼中分離出來,然后:
- 將設(shè)備代碼編譯為匯編形式(PTX代碼) 和/或二進(jìn)制形式(cubin對象),
- 通過替換<<<…>>>語法在kernel中引入(并在執(zhí)行配置中詳細(xì)描述),通過必要的CUDA運(yùn)行時(shí)函數(shù)調(diào)用從PTX代碼和/或cubin對象加載和啟動(dòng)每個(gè)編譯的內(nèi)核。
修改后的主機(jī)代碼要么以c++代碼的形式輸出,留待使用其他工具編譯。要么在最后編譯階段讓nvcc調(diào)用主機(jī)編譯器,直接以目標(biāo)代碼的形式輸出。
應(yīng)用程序可以:
- 鏈接到已編譯的主機(jī)代碼(這是最常見的情況),
- 或者忽略修改過的主機(jī)代碼(如果有的話),并使用CUDA驅(qū)動(dòng)程序API(參見驅(qū)動(dòng)程序API)來加載和執(zhí)行PTX代碼或立方體對象。
Just-in-Time Compilation
應(yīng)用程序在運(yùn)行時(shí)加載的任何 PTX 或 NVVM IR 代碼都被設(shè)備驅(qū)動(dòng)程序進(jìn)一步編譯為二進(jìn)制代碼。這被稱為即時(shí)編譯。即時(shí)編譯增加了應(yīng)用程序的加載時(shí)間,但允許應(yīng)用程序從每個(gè)新設(shè)備驅(qū)動(dòng)程序帶來的任何新的編譯器改進(jìn)中受益。這也是讓應(yīng)用程序在編譯應(yīng)用程序時(shí)還不存在的設(shè)備上運(yùn)行的唯一方法,詳見應(yīng)用程序兼容性。
當(dāng)設(shè)備驅(qū)動(dòng)程序?yàn)槟硞€(gè)應(yīng)用程序?qū)崟r(shí)編譯一些PTX或NVVM IR代碼時(shí),它會(huì)自動(dòng)緩存生成的二進(jìn)制代碼的副本,以避免在后續(xù)的應(yīng)用程序調(diào)用中重復(fù)編譯 。當(dāng)設(shè)備驅(qū)動(dòng)程序升級時(shí),緩存(稱為compute cache)將自動(dòng)失效,因此應(yīng)用程序可以從設(shè)備驅(qū)動(dòng)程序中內(nèi)置的新即時(shí)編譯器的改進(jìn)中受益。
作為使用nvcc編譯CUDA c++設(shè)備代碼的替代方案,NVRTC可以在運(yùn)行時(shí)將CUDA c++設(shè)備代碼編譯為PTX。NVRTC是CUDA c++的運(yùn)行時(shí)編譯庫。
Binary Compatibility
二進(jìn)制代碼是特定于體系結(jié)構(gòu)的 。cubin對象是使用指定目標(biāo)體系結(jié)構(gòu)的編譯器選項(xiàng)-code生成的.例如,使用-code=sm_35編譯會(huì)為計(jì)算能力為3.5的設(shè)備生成二進(jìn)制代碼。二進(jìn)制兼容性可以保證從一個(gè)小修訂到下一個(gè)小修訂,但不能保證從一個(gè)小修訂到前一個(gè)小修訂或跨多個(gè)大修訂。換句話說,為計(jì)算能力X.y生成的立方對象將只在計(jì)算能力X.z的設(shè)備上執(zhí)行,其中z≥y。
設(shè)備的compute capability由版本號(hào)表示,有時(shí)也稱為“ SM version ”
PTX Compatibility
一些PTX指令只在具有較高計(jì)算能力的設(shè)備上支持。例如,Warp Shuffle Functions僅在計(jì)算能力3.0及以上的設(shè)備上支持。-arch compiler選項(xiàng)指定在將c++編譯為PTX代碼時(shí)所假定的計(jì)算能力。因此,例如,包含warp shuffle的代碼必須使用-arch=compute_30(或更高)編譯。
為某些特定計(jì)算能力而產(chǎn)生的PTX代碼總是可以編譯成具有更大或同等計(jì)算能力的二進(jìn)制代碼 。注意,從較早的PTX版本編譯的二進(jìn)制文件可能不能使用某些硬件特性。例如,由計(jì)算能力6.0 (Pascal)生成的PTX編譯的計(jì)算能力7.0 (Volta)的二進(jìn)制目標(biāo)設(shè)備將不會(huì)使用張量核心指令,因?yàn)檫@些在Pascal上是不可用的。因此,最終的二進(jìn)制代碼可能比使用PTX的最新版本生成的二進(jìn)制代碼的性能更差。
Application Compatibility
要在具有特定計(jì)算能力的設(shè)備上執(zhí)行代碼,應(yīng)用程序必須加載與該計(jì)算能力兼容的二進(jìn)制或PTX代碼。特別是,為了能夠在未來具有更高計(jì)算能力的體系結(jié)構(gòu)上執(zhí)行代碼(目前還不能生成二進(jìn)制代碼),應(yīng)用程序必須加載為這些設(shè)備實(shí)時(shí)編譯的PTX代碼(參見實(shí)時(shí)編譯)。
哪一個(gè)PTX和二進(jìn)制代碼嵌入CUDA c++應(yīng)用程序是由-arch和-code編譯器選項(xiàng)或-gencode編譯器選項(xiàng)控制的,詳見nvcc用戶手冊。例如:
nvcc x.cu
-gencode arch=compute_50,code=sm_50
-gencode arch=compute_60,code=sm_60
-gencode arch=compute_70,code=\\"compute_70,sm_70\"
嵌入與計(jì)算能力5.0和6.0兼容的二進(jìn)制代碼(第一個(gè)和第二個(gè)-gencode選項(xiàng)),以及與計(jì)算能力7.0兼容的PTX和二進(jìn)制代碼(第三個(gè)-gencode選項(xiàng))。
生成主機(jī)代碼以在運(yùn)行時(shí)自動(dòng)選擇最合適的代碼來加載和執(zhí)行,在上面的例子中,將是:
- 5.0二進(jìn)制代碼用于具有5.0和5.2計(jì)算能力的設(shè)備
- 6.0二進(jìn)制代碼用于具有6.0和6.1計(jì)算能力的設(shè)備
- 7.0二進(jìn)制代碼用于具有7.0和7.5計(jì)算能力的設(shè)備
- PTX代碼,在運(yùn)行時(shí)編譯為二進(jìn)制代碼,用于具有8.0和8.6計(jì)算能力的設(shè)備。
x.cu可以有一個(gè)使用扭曲洗刷操作的優(yōu)化代碼路徑,例如,這只在計(jì)算能力3.0及更高的設(shè)備中得到支持??梢允褂?code>__CUDA_ARCH__宏根據(jù)計(jì)算能力區(qū)分不同的代碼路徑。它僅為設(shè)備代碼定義。例如,當(dāng)使用-arch=compute_35編譯時(shí),__CUDA_ARCH__等于350.
C++ Compatibility
編譯器前端根據(jù)c++語法規(guī)則處理CUDA源文件。主機(jī)代碼支持完全c++。然而,設(shè)備代碼只完全支持c++的一個(gè)子集.
64-Bit Compatibility
64位版本的nvcc以64位模式編譯設(shè)備代碼(即指針為64位)。64位編譯的設(shè)備代碼只支持64位編譯的主機(jī)代碼。
同樣,32位版本的nvcc以32位模式編譯設(shè)備代碼,32位模式編譯的設(shè)備代碼只支持32位模式編譯的主機(jī)代碼。
- 32位版本的nvcc可以使用
-m64編譯器選項(xiàng)在64位模式下編譯設(shè)備代碼。 - 64位版本的nvcc可以使用
-m32編譯器選項(xiàng)在32位模式下編譯設(shè)備代碼。
電子發(fā)燒友App









































評論