2012-01-29 97 views
6

我想了解OpenCL設備(如GPU)的體系結構,但我無法瞭解爲什麼在本地工作組中的工作項數(即常量CL_DEVICE_MAX_WORK_GROUP_SIZE)上存在顯式限制。爲什麼會有CL_DEVICE_MAX_WORK_GROUP_SIZE?

在我看來,這應該由編譯器負責,也就是說,如果一個(爲了簡單起見,一維)內核在本地工作組大小爲500而其物理最大值爲100的情況下執行,並且內核查找示例像這樣:

__kernel void test(float* input) { 
    i = get_global_id(0); 
    someCode(i); 
    barrier(); 
    moreCode(i); 
    barrier(); 
    finalCode(i); 
} 

那麼它可以自動轉換爲與工作組大小100執行這一內核:

__kernel void test(float* input) { 
    i = get_global_id(0); 
    someCode(5*i); 
    someCode(5*i+1); 
    someCode(5*i+2); 
    someCode(5*i+3); 
    someCode(5*i+4); 
    barrier(); 
    moreCode(5*i); 
    moreCode(5*i+1); 
    moreCode(5*i+2); 
    moreCode(5*i+3); 
    moreCode(5*i+4); 
    barrier(); 
    finalCode(5*i); 
    finalCode(5*i+1); 
    finalCode(5*i+2); 
    finalCode(5*i+3); 
    finalCode(5*i+4); 
} 

但是,似乎這是不是默認設置。爲什麼不?有沒有辦法使這個過程自動化(除了自己編寫一個預編譯器)?還是有一個內在的問題,可以使我的方法在某些例子上失敗(你能給我一個)?

+0

它會在一個序列中放五個函數調用,不是嗎?所以這隻會是某種退步。此外,您還必須確保將工作維度填充到五的倍數。只是想知道.. – rdoubleui 2012-01-29 20:47:46

回答

4

我認爲CL_DEVICE_MAX_WORK_GROUP_SIZE的來源在於底層的硬件實現。

多個線程同時運行在計算單元上,並且每個線程都需要保持狀態(對於call,jmp等)。大多數實現爲此使用堆棧,如果您查看AMD Evergreen系列,它們是可用堆棧條目數量的硬件限制(每個堆棧條目都有子條目)。這實質上限制了每個計算單元可以同時處理的線程數量。

至於編譯器可以做到這一點,使之成爲可能。它可以工作,但明白這意味着重新編譯內核。這並不總是可能的。我可以想象開發人員爲每個平臺以二進制格式轉儲已編譯內核的情況,並且只是爲了「不那麼開源」的原因將其與他們的軟件一起發貨。

+0

+1的二進制內核,將是一個明確的限制因素。 – rdoubleui 2012-01-29 22:21:18

0

這些常量是由編譯器從設備查詢的,以便在編譯時確定合適的工作組大小(編譯當然是指編譯內核)。我可能會弄錯你的想法,但你似乎想要自己設定這些值,事實並非如此。

責任是在您的代碼中查詢系統功能,以準備好運行的任何硬件。