2013-03-10 27 views
0

是否有可能使cuda使用在函數外聲明的單線程作用域變量(寄存器或本地內存)?Cuda單線程作用域變量

我的大部分設備功能需要使用相同的變量。

我不想將與變量相同的變量作爲參數傳遞給我的所有設備函數,我想在函數之外聲明變量。

這可能嗎?

我的計算能力是1.2。

編輯:一個例子:

__device__ __local__ int id; 
__device__ __local__ int variable1 = 3; 
__device__ __local__ int variable2 = 5; 
__device__ __local__ int variable3 = 8; 
__device__ __local__ int variable4 = 8; 

// 
__device__ int deviceFunction3() { 
    variable1 += 8; 
    variable4 += 7; 
    variable2 += 1; 
    variable3 += id; 

    return variable1 + variable2 + variable3; 
} 

__device__ int deviceFunction2() { 
    variable3 += 8; 
    variable1 += deviceFunction3(); 
    variable4 += deviceFunction3(); 

    return variable3 + variable4; 
} 

__device__ int deviceFunction1() { 
    variable1 += id; 
    variable4 += 2; 
    variable2 += deviceFunction2(); 
    variable3 += variable2 + variable4; 
    return variable1 + variable2 + variable3 + variable4; 
} 

// Kernel 
__global__ void kernel(int *dev_a, int *dev_b, int *dev_c) { 
    id = get_id(); 

    dev_c[id] = deviceFunction1(); 
} 

3個設備功能需要操縱相同的變量。每個變量都依賴於每個線程計算。據我的理解,我不能使用上面的代碼,因爲我不能聲明變量,以便它們對於每個線程都是本地的。

我必須做的,而不是正在申報核函數中的所有變量,然後將指針傳遞給變量的所有其他功能:

__device__ int deviceFunction3(int* id,int* variable1,int* variable2,int* variable3,int* variable4) { 
    *variable1 += 8; 
    *variable4 += 7; 
    *variable2 += 1; 
    *variable3 += 2; 

    return *variable1 + *variable2 + *variable3; 
} 

__device__ int deviceFunction2(int* id,int* variable1,int* variable2,int* variable3,int* variable4) { 
    *variable3 += 8; 
    *variable1 += deviceFunction3(id,variable1,variable2,variable3,variable4); 
    *variable4 += deviceFunction3(id,variable1,variable2,variable3,variable4); 

    return *variable3 + *variable4; 
} 

__device__ int deviceFunction1(int* id,int* variable1,int* variable2,int* variable3,int* variable4) { 
    *variable1 += *id; 
    *variable4 += 2; 
    *variable2 += deviceFunction2(id,variable1,variable2,variable3,variable4); 
    *variable3 += *variable2 + *variable4; 
    return *variable1 + *variable2 + *variable3 + *variable4; 
} 

// Kernel 
__global__ void kernel(int *dev_a, int *dev_b, int *dev_c) { 
    int id = get_id(); 
    int variable1 = 3; 
    int variable2 = 5; 
    int variable3 = 8; 
    int variable4 = 8; 

    dev_c[id] = deviceFunction1(&id,&variable1,&variable2,&variable3,&variable4); 
} 
+2

你能否給你的問題添加一個用例的例子?包含變量和\ _ \ _ device \ _ \ _函數的類是否工作? – talonmies 2013-03-10 15:22:43

+0

如果有'__device__'知道它屬於哪個線程的方式,但我不認爲有這樣的事情。 (即使它不能訪問寄存器,但它可以訪問全局定義的數組作爲每個線程的本地變量,即使如此,性能也會降低很多!) – 2013-03-10 15:59:29

+1

沒有辦法讓一個線程CUDA中文件範圍的私有變量。特別是,我不相信有辦法在PTX中支持它。 – 2013-03-11 09:38:09

回答

3

您的使用案例是一個真正糟糕的想法,我不會向我最大的敵人推薦這種設計模式。撇開代碼的優點了一會兒,因爲我在評論中暗示,可以實現線程局部變量的作用域你通過封裝__device__函數和變量的願望,他們依靠的結構,像這樣:

struct folly 
{ 
    int id; 
    int variable1; 
    int variable2; 
    int variable3; 
    int variable4; 

    __device__ folly(int _id) { 
     id = _id; 
     variable1 = 3; 
     variable2 = 5; 
     variable3 = 8; 
     variable4 = 8; 
    } 

    __device__ int deviceFunction3() { 
     variable1 += 8; 
     variable4 += 7; 
     variable2 += 1; 
     variable3 += id; 

     return variable1 + variable2 + variable3; 
    } 

    __device__ int deviceFunction2() { 
     variable3 += 8; 
     variable1 += deviceFunction3(); 
     variable4 += deviceFunction3(); 

     return variable3 + variable4; 
    } 

    __device__ int deviceFunction1() { 
     variable1 += id; 
     variable4 += 2; 
     variable2 += deviceFunction2(); 
     variable3 += variable2 + variable4; 
     return variable1 + variable2 + variable3 + variable4; 
    } 
}; 

__global__ void kernel(int *dev_a, int *dev_b, int *dev_c) { 
    int id = threadIdx.x + blockIdx.x * blockDim.x; 
    folly do_calc(id); 
    dev_c[id] = do_calc.deviceFunction1(); 
} 

還要注意,CUDA支持通過引用C++式通,所以已寫入第二片的您發佈代碼的設備功能中的任何一個可以很容易地這樣寫的:

__device__ int deviceFunction3(int & variable1, int & variable2, 
           int & variable3, int & variable4) 
{ 
    variable1 += 8; 
    variable4 += 7; 
    variable2 += 1; 
    variable3 += 2; 

    return variable1 + variable2 + variable3; 
} 

遠遠清潔和更容易讀書。

+0

我希望以這種「可怕」的方式設計代碼,正如您可能已經猜到的那樣,來自面向對象的思路。在面向對象的語言中,像這樣的局部變量是非常有意義的。我不瞭解C,我意識到。 感謝您向我展示C++風格的通過引用,這將使我的代碼更清潔! – mollerhoj 2013-03-11 10:41:39

+0

@mollerhoj我相信C++是OOP語言。你爲什麼不使用這個並且申明一個合適的類? – KiaMorot 2013-03-12 08:28:11

-1

我只是想補充一點,我的結論是這不可能。我發現它是CUDA C的一個主要設計問題。

我在某些幻燈片中看到了一個名爲__local__的關鍵字,但我找不到任何文檔,並且nvcc也無法識別它。

我想所有應該只有一個線程範圍的變量只能在函數內部聲明。

+2

回答要求澄清的問題是否合理?從@talonmies,在宣佈沒有解決方案之前? C或任何其他語言是否允許將特定範圍的變量定義在該範圍之外?如果是的話你能提供一個例子嗎? – 2013-03-10 23:14:02

+0

對不起,我現在已經添加了一個例子,我希望能夠向@talonmies和你解釋我的問題就足夠了。 – mollerhoj 2013-03-11 08:46:00