线程之间的CUDA共享对象

线程之间的CUDA共享对象,cuda,Cuda,我是CUDA的新手。我想在设备上创建一个对象,并从不同线程访问其成员。我使用nvcc-arch=sm_20(在特斯拉M2090上),如果我运行我的代码,我会得到一个“未指定的启动失败”。这是我的密码: #include <stdio.h> #include <string> using namespace std; #ifdef __CUDACC__ #define CUDA_CALLABLE __host__ __device__ #else #define CUD

我是CUDA的新手。我想在设备上创建一个对象,并从不同线程访问其成员。我使用nvcc-arch=sm_20(在特斯拉M2090上),如果我运行我的代码,我会得到一个“未指定的启动失败”。这是我的密码:

#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;
}
#包括
#包括
使用名称空间std;
#ifdef_u_CUDACC__
#定义CUDA可调用主机设备__
#否则
#定义CUDA_可调用
#恩迪夫
类SimpleClass{
公众:
int i;
CUDA_可调用SimpleClass(){i=1;};
CUDA_可调用~SimpleClass(){};
};
__全局无效初始化内核(SimpleClass*a){
a=新的SimpleClass();
}
__全局虚delkernel(SimpleClass*a){
删除一条;
}
__全局无效内核(SimpleClass*a){
printf(“%d\n”,a->i);
}
int main(){
简单类*a;
初始内核(a);
cudaThreadSynchronize();
内核(a);
cudaThreadSynchronize();
delkernel(a);
cudaThreadSynchronize();
cudaError_t error=cudaGetLastError();
字符串lastError=cudaGetErrorString(错误);
printf(“%s\n”,lastError.c_str());
返回0;
}

在第一个内核代码期间,您会遇到“未指定的启动失败”,因为“a”是存储在主机中的指针,但您希望从设备函数中为其指定一个值。如果要在设备上分配对象,首先必须在设备上分配一个指针,然后才能从设备(内核)代码中读取和写入该指针,但要小心,因为这将需要双重间接寻址

您的代码应该如下所示(其他函数应该进行类似的修改):

\uuuuu全局\uuuuu无效初始化内核(SimpleClass**a){
*a=新的SimpleClass();
}
int main(){
简单类**a;
Cudamaloc((void**)和sizeof(SimpleClass**));
初始内核(a);
cudaThreadSynchronize();
}

PS:pQB在这一点上是绝对正确的,您应该在每个内核代码之后进行错误检查,以尽快检测错误(目前是为了在代码中找到错误的确切位置)

您应该在
每个
内核调用之后而不是在最后检查错误。这也适用于任何CUDA API调用。您可以尝试使用CUDA memcheck运行应用程序并发布结果吗?
__global__ void initkernel(SimpleClass** a){
    *a = new SimpleClass();
}

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