2011-05-23 62 views
1

我正在开发一个通用流式CUDA内核执行框架,允许在GPU上执行并行数据复制&。是否存在某种与Boost :: thread()和Nvidia CUDA的不兼容?

目前我正在调用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上,我需要创建一个线程,所以当我把它做一个新的boost ::线程:

//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 &提升的问题吗?我错过了什么吗?谢谢你的建议。

回答

4

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

如果你想以这种方式使用线程,你需要重构一些东西,以便一个线程只与GPU“交谈”,并通过CPU内存与父进程通信,或者使用CUDA上下文迁移API,允许上下文从一个线程移动到另一个线程(通过cuCtxPushCurrent和cuCtxPopCurrent)。请注意,上下文迁移不是免费的,并且存在延迟,因此如果您计划频繁迁移上下文,则可能会发现切换到保留上下文线程亲和性的其他设计会更有效。

+0

谢谢,我会尝试重新设计 – Vik 2011-05-24 08:53:21

+0

是的,那真的很有用,再次感谢你。我永远无法通过我自己的方式找出它:) – Vik 2011-05-24 12:37:37

+0

为什么你需要多线程才能让内核执行和cudaMemcpy重叠?这就是cudaMemcpyAsync的用途,对吧? – harrism 2011-05-25 03:14:38