2013-03-22 210 views
0

我對CUDA完全陌生。我想在設備上創建一個對象,並從不同的線程訪問其成員。我使用nvcc -arch = sm_20(在Tesla M2090上),如果我運行我的代碼,我會得到'未指定的啓動失敗'。這裏是我的代碼:線程之間的CUDA共享對象

#include <stdio.h> 
#include <string> 

using namespace std; 

#ifdef __CUDACC__ 
#define CUDA_CALLABLE __host__ __device__ 
#else 
#define CUDA_CALLABLE 
#endif 

class SimpleClass { 
public: 
    int i; 
    CUDA_CALLABLE SimpleClass(){i=1;}; 
    CUDA_CALLABLE ~SimpleClass(){}; 
}; 

__global__ void initkernel(SimpleClass *a){ 
    a = new SimpleClass(); 
} 
__global__ void delkernel(SimpleClass *a){ 
    delete a; 
} 
__global__ void kernel(SimpleClass *a){ 
printf("%d\n", a->i); 
} 

int main() { 
    SimpleClass *a; 
    initkernel<<<1,1>>>(a); 
    cudaThreadSynchronize(); 
    kernel<<<1,10>>>(a); 
    cudaThreadSynchronize(); 
    delkernel<<<1,1>>>(a); 
    cudaThreadSynchronize(); 

    cudaError_t error = cudaGetLastError(); 
    string lastError = cudaGetErrorString(error); 
    printf("%s\n",lastError.c_str()); 
    return 0; 
} 
+0

您應該檢查每個內核調用後發生的錯誤,而不是在最後。這也適用於任何CUDA API調用。 – pQB 2013-03-22 15:51:30

+0

你可以試着用cuda-memcheck運行你的應用程序併發布結果嗎? – Vyas 2013-03-22 22:23:58

回答

0

你的第一個內核代碼中得到「未指定發射失敗」,因爲「A」是存儲在主機的指針,但你想給它從一個設備功能的價值。如果你想在設備上分配對象,比你首先必須在設備上分配一個指針,並且你可以讀寫設備(內核)代碼,但要小心,因爲它需要雙重間接。

您的代碼應該看起來像這樣的事情(的其餘功能應同樣修改):

__global__ void initkernel(SimpleClass** a){ 
    *a = new SimpleClass(); 
} 

int main() { 
    SimpleClass** a; 
    cudaMalloc((void**)&a, sizeof(SimpleClass**)); 
    initkernel<<<1,1>>>(a); 
    cudaThreadSynchronize(); 
} 

PS:PQB是絕對正確的是,你應該做的每個內核之後的錯誤檢查代碼儘快檢測錯誤(並且目前用於查找代碼中錯誤的確切位置)

+0

謝謝SqrtPi,你的建議解決了這個問題。 – robogos 2013-03-23 05:56:00