cuda - 防止 CUDA 中的内核调用后析构函数调用

标签 cuda raii

考虑我的问题的简化版本:为了将数据传递到 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/

相关文章:

c++ - 在 C++ 中实现 "contextmanager"的最佳实践 + 语法

c++ - 如何限制构造生命周期更长的对象所需的变量范围?

c++ - 我的类的构造函数应该执行多少工作?

Cuda,3d block 中的执行线程顺序

c - CUDA代码的数据收集部分意外输出“0”

python - 无法编译 cuda_ndarray.cu : libcublas. so.7.5:无法打开共享对象文件

c - NVAPI 设备 ID 与 CUDA 设备 ID 有何关系?

cuda - cuda中的预取(通过C代码)

c++ - 私有(private)新运营商是否有任何意想不到的副作用?

c++ - 如何理解 pthread_cancel 原因 "terminate called without an active exception"?