考虑我的问题的简化版本:为了将数据传递到 CUDA 内核,我使用一个类来保存数据和指向图形硬件上的数据的指针。
class A {
int data;
float* dataOnGPU;
A() { cudaMalloc( dataOnGPU ... ); }
~A() { cudaFree( dataOnGPU ... ); }
};
void myFunction()
{
A obj;
kernelCall1<<<1,1>>>( obj );
kernelCall2<<<1,1>>>( obj ); // obj.dataOnGPU no longer points to valid memory
}
从第一个内核调用返回会导致调用 obj 副本的析构函数(因为内核是按值调用的,这会创建一个副本)。这会释放 obj 及其副本的 dataOnGPU。 obj.dataOnGPU 的内存在 obj 超出范围之前不应释放。
当然,有可能避免这种情况,但我希望拥有良好且干净的 RAII 行为。有什么建议吗?
最佳答案
使用自定义复制构造函数是解决方案:
class A {
int data;
float* dataOnGPU;
bool isCopy;
A() { cudaMalloc( dataOnGPU ... ); isCopy = false; }
A( const A& _orig ) { *this = _orig; isCopy = true; }
~A() { if (!isCopy) cudaFree( dataOnGPU ... ); }
};
void myFunction()
{
A obj;
kernelCall1<<<1,1>>>( obj );
kernelCall2<<<1,1>>>( obj ); // obj.dataOnGPU still points to valid memory
}
感谢 Paul R 间接向我指出了这一点:)
关于cuda - 防止 CUDA 中的内核调用后析构函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19005360/