網格同步(Grid Synchronization):
在引入協作組之前,CUDA程式設計模型隻允許在核心完成邊界上的線程塊之間進行同步。 核心邊界帶有隐含的狀态無效,并帶有潛在的性能影響。
例如,在某些使用情況下,應用程式擁有大量的小核心,每個核心代表處理管道中的一個階段。 目前CUDA程式設計模型需要這些核心的存在,以確定在一個流水線階段上運作的線程塊在下一個流水線階段運作的線程塊準備好使用之前生成資料。 在這種情況下,提供全局線程間塊同步的能力将允許應用程式重新建構為具有持久線程塊,當給定階段完成時,這些線程塊能夠在裝置上進行同步。
要在核心中同步整個網格,您隻需使用該組:
調用:
要啟用網格同步,啟動核心時,需要使用cuLaunchCooperativeKernel CUDA運作時啟動API,而不是<<< ... >>>執行配置文法:
(或等效的CUDA驅動程式)。
為了保證GPU上的線程塊的共同駐留,需要仔細考慮啟動的塊的數量。 例如,每個SM的塊可以按如下方式啟動:
或者,您可以使用占用率電腦計算每SM可同時容納多少個塊,如下所示:
還要注意,要使用網格同步,必須在單獨的編譯中編譯器件代碼(請參閱CUDA編譯器驅動程式NVCC文檔中的“在CUDA中使用獨立編譯”一節)以及連結的器件運作時。最簡單的示例是:
您還應該確定裝置支援協作啟動屬性,這可以通過使用cuDeviceAttribute CUDA驅動程式API來确定:
如果在裝置0上支援該屬性,将會将pi設定為1。
多裝置同步:
為了啟用多個裝置與協同組之間的同步,需要使用cuLaunchCooperativeKernelMultiDevice CUDA API。 這與現有的CUDA API顯着不同,将允許單個主機線程跨多個裝置啟動核心。 除了cuLaunchCooperativeKernel所做的限制和保證外,這個API還有其他的語義:
該API将確定啟動是原子級的,即,如果API調用成功,則提供的線程塊數将在所有指定的裝置上啟動。
通過此API啟動的功能必須相同。 驅動在這方面沒有進行明确的檢查,因為這在很大程度上是不可行的。 確定這一點取決于應用程式。
提供的launchParamsList中沒有兩個條目可映射到同一裝置。
本次釋出所針對的所有裝置必須完全相同。 即它們必須具有相同的主号碼和次号碼。
所有裝置的塊大小,網格大小和每個網格的共享記憶體數量必須相同。 請注意,這意味着每個裝置可以啟動的塊的最大數量将受SM數量最少的裝置的限制。
擁有正在啟動的CU函數的子產品中存在的任何使用者定義的<code>__device__</code>,<code>__constant__</code>或<code>__managed__</code>裝置全局變量将在每個裝置上獨立執行個體化。 使用者負責适當地初始化這些裝置全局變量。
啟動參數應該使用struct定義:
并傳入啟動API:
以類似于上述網格範圍同步的方式。 另外,與網格同步一樣,生成的裝置代碼看起來非常相似:
并需要在單獨的編譯中進行編譯。
您還應該確定裝置支援協作式多裝置啟動屬性,其方式與上一節中所述類似,但使用CU_DEVICE_ATTRIBUTE_COOPERATIVE_MULTI_DEVICE_LAUNCH而不是CU_DEVICE_ATTRIBUTE_COOPERATIVE_LAUNCH。
