【问题标题】:CUDA 5.0 context management with single application thread in multiple GPU environmentCUDA 5.0 上下文管理与多 GPU 环境中的单个应用程序线程
【发布时间】:2013-01-28 02:45:20
【问题描述】:

似乎大多数来自网络的教程、指南、书籍和问答都提到了 CUDA 3 和 4.x,所以这就是我专门询问 CUDA 5.0 的原因。问题...

我想为一个有两个 CUDA 设备的环境编程,但只使用一个线程,以简化设计(特别是因为它是一个原型)。我想知道以下代码是否有效:

float *x[2];
float *dev_x[2];

for(int d = 0; d < 2; d++) {
    cudaSetDevice(d);
    cudaMalloc(&dev_x[d], 1024);
}

for(int repeats = 0; repeats < 100; repeats++) {
    for(int d = 0; d < 2; d++) {
        cudaSetDevice(d);
        cudaMemcpy(dev_x[d],x[d],1024,cudaMemcpyHostToDevice);

        some_kernel<<<...>>>(dev_x[d]);

        cudaMemcpy(x[d],dev_x[d],1024,cudaMemcpyDeviceToHost);
    }
    cudaStreamSynchronize(0);
}

我想具体了解测试之前的cudaMalloc(...)s 是否持续存在,即使cudaSetDevice() 的交换发生在同一个线程中。另外,我想知道 cudaEvent_tcudaStream_t 等依赖于上下文的对象是否也会发生同样的情况。

我之所以问它是因为我有一个这种风格的应用程序,它不断出现一些映射错误,如果缺少内存泄漏或错误的 API 使用,我找不到它是什么。

注意:在我的原始代码中,我会检查每个 CUDA 调用。为了代码的可读性,我没有把它放在这里。

【问题讨论】:

  • 您不必调用 cudaStreamSynchronize() 因为 cudaMemcpy() 调用是同步的。另外,请注意,在您的循环终止后,设备 1 将是 CPU 线程的当前线程。

标签: c++ memory-management cuda multiple-gpu cuda-context


【解决方案1】:

这只是一个错字吗?

for(int d = 0; d < 2; d++) {
    cudaSetDevice(0);  // shouldn't that be 'd'
    cudaMalloc(&dev_x, 1024);
}

请检查所有API调用的返回值!

【讨论】:

  • 是的,应该没问题。由 cudaMalloc、流和事件分配的区域都特定于创建它们的设备(最近的 cudaSetDevice() 调用)。因此,您应该确保仅使用与您正在访问的设备相关的那些项目。附加信息here。此外,x[d] 因为它存在于主机上,所以除非您愿意,否则不需要为每个设备编制索引。
  • 是否同样适用于依赖于上下文的对象,例如流和事件?
  • 如果不是拼写错误并且所有 API 调用都返回成功,那么您问题中的信息似乎不足以识别您的问题,因为它看起来没问题(尽管有不必要的 cudaStreamSynchronize())。你可以尝试创建一个复制品吗?您还可以尝试使用 cuda-memcheck 运行以查找 OOB 错误和泄漏(使用泄漏检查选项)。
猜你喜欢
  • 2022-11-10
  • 1970-01-01
  • 2019-10-25
  • 1970-01-01
  • 2015-10-17
  • 1970-01-01
  • 1970-01-01
  • 2014-05-14
  • 2013-10-29
相关资源
最近更新 更多