Boost::thread()和Nvidia CUDA是否存在某种不兼容



我正在开发一个通用的流式CUDA内核执行框架,它允许并行数据复制&在GPU上执行。

目前,我正在C++静态函数包装器中调用cuda内核,因此我可以从.cpp文件(而不是.cu)中调用内核,如下所示:

//kernels.cu:
//kernel definition
__global__ void kernelCall_kernel(  dataRow* in,  dataRow* out,  void* additionalData){
    //Do something
};
//kernel handler, so I can compile this .cu and link it with the main project and call it within a .cpp file
extern "C" void kernelCall( dataRow* in,  dataRow* out,  void* additionalData){ 
    int blocksize = 256;  
    dim3 dimBlock(blocksize);
    dim3 dimGrid(ceil(tableSize/(float)blocksize)); 
    kernelCall_kernel<<<dimGrid,dimBlock>>>(in, out, additionalData);   
}

如果我将处理程序作为一个普通函数调用,则打印的数据是正确的。

//streamProcessing.cpp
//allocations and definitions of data omitted
//copy data to GPU
cudaMemcpy(data_d,data_h,tableSize,cudaMemcpyHostToDevice);
//call:
kernelCall(data_d,result_d,null);
//copy data back
cudaMemcpy(result_h,result_d,resultSize,cudaMemcpyDeviceToHost);
//show result:
printTable(result_h,resultSize);// this just iterate and shows the data

但是,为了允许在GPU上并行复制和执行数据,我需要创建一个线程,所以当我调用它时,会进行新的提升::thread:

//allocations, definitions of data,copy data to GPU omitted
//call:
boost::thread* kernelThreadOwner = new boost::thread(kernelCall, data_d,result_d,null); 
kernelThreadOwner->join();
//Copy data back and print ommited

我只是在最后打印结果时收到垃圾。

目前,我只是使用一个线程进行测试,所以直接调用它或创建一个线程应该没有太大区别。我不知道为什么直接调用函数会得到正确的结果,而当创建线程时却不会。这是CUDA&促进我是不是错过了什么?谢谢你的建议。

问题是(CUDA 4.0之前)CUDA上下文绑定到创建它们的线程。当您使用两个线程时,您有两个上下文。主线程正在分配和读取的上下文与运行内核的线程内部的上下文不相同。内存分配在上下文之间是不可移植的。它们实际上是同一GPU内的独立内存空间。

如果你想以这种方式使用线程,你需要重构一些东西,使一个线程只与GPU"对话",并通过CPU内存与父线程通信,或者使用CUDA上下文迁移API,它允许上下文从一个线程移动到另一个线程(通过cuCtxPushCurrent和cuCtxPopCurrent)。请注意,上下文迁移不是免费的,而且会涉及延迟,因此,如果您计划频繁地迁移上下文,您可能会发现更改为不同的设计会更有效,从而保持上下文线程的相关性。

相关内容