【问题标题】:Proper use of cudaDeviceReset()正确使用 cudaDeviceReset()
【发布时间】:2013-05-31 04:54:53
【问题描述】:

由于我怀疑“黑匣子”(GPU)在一些较大的代码(others perhaps too)中没有完全关闭,我会在main() 的末尾添加一个cudaDeviceReset()。可是等等!这将Segmentation faultmain() 中静态创建的所有类实例在析构函数中使用非平凡的CUDA 代码,对吧?例如

class A {
public:
  cudaEvent_t tt;
  cudaEvent_t uu;
  A() { 
    cudaEventCreate(&tt);
    cudaEventCreate(&uu);
  }
  ~A(){  
    cudaEventDestroy(tt);
    cudaEventDestroy(uu);
  }
};

静态实例化:

int main() {
  A t;
  cudaDeviceReset();
  return 0;
} 

退出时出现段错误。问题:在退出main() 时是否会自动调用cudaDeviceReset()

否则main() 的整个有用代码应该转移到某个run(),并且cudaDeviceReset() 应该是main() 中的最后一个命令,对吧?

【问题讨论】:

  • cudaDeviceReset 显式销毁由调用它的进程或线程持有的活动设备上的任何上下文。但它所做的一切。如果您有 CUDA API 调用需要上下文才能在析构函数代码中工作,那么您不能在上下文已经销毁后调用它们(并且在进程终止时它将被运行时自动销毁)。

标签: cuda


【解决方案1】:

正如 Talonmies 所指出的,类 A 的析构函数是在 cudaDeviceReset() 函数被调用之后调用的,即 main(..) 函数完成时。

我认为,您可以将 cudaDeviceReset() 用于 atexit(..) 函数。

void myexit() {
  cudaDeviceReset();
}

int main(...) {
  atexit(myexit); 
  A t;
  return 0;
}

【讨论】:

  • 因此您可以尝试在另一个括号中声明“t”。然后在这个括号结束后调用 cudaDeviceReset 。所以它可能会在设备重置之前强制销毁“t”.. """int main(..) { { A t; t.someoperation(); } cudaDeviceReset(); }"""
  • 谢谢。我认为这是一个很好的观点。我会尽快检查并通知您。
  • Talonmies 在CUDA streams destruction and CudaDeviceReset 就这个话题进行了有趣的讨论。
  • 是的,Talonmies 是王者,特别是如果主题是 CUDA。我真的很好奇他回答了哪些与 CUDA 相关的问题。让我们来看看。谢谢Talonmies。
猜你喜欢
  • 1970-01-01
  • 2013-06-03
  • 1970-01-01
  • 2016-06-30
  • 1970-01-01
  • 2020-10-28
  • 1970-01-01
  • 2018-11-03
  • 1970-01-01
相关资源
最近更新 更多