【问题标题】:How to run CPU and GPU function simultaneously using threads?如何使用线程同时运行 CPU 和 GPU 功能?
【发布时间】:2018-12-09 09:07:37
【问题描述】:

我有两个要使用线程运行的函数。

1) CPU 函数,我可以使用它加入线程:

thread t1(vector_add, p->iNum1, p->iNum2, p->iNumAns, p->flag);
t1.join();

2) 和一个 GPU 内核

vectorAdd_gpu <<<blocksPerGrid, threadsPerBlock >>>(s.a1, s.a2, s.a2, s.flag);

但我的问题是如何使用线程调用GPU内核调用并加入它,以便它可以与CPU功能同时运行。

vectorAdd_gpu <<<blocksPerGrid, threadsPerBlock >>>(s.a1, s.a2, s.a2, s.flag);

thread t2(vectorAdd_gpu);
t2.join();

还有其他方法可以使用线程同时运行 CPU 和 GPU 功能吗?

【问题讨论】:

  • 写一个包装函数?
  • 这是什么语言?
  • @AnttiHaapala:CUDA,即不是 C.
  • 我不了解 Jack 的 GPU 编程,但是如果运行在 GPU 上的代码和运行在 CPU 上的代码不是都运行在同一个虚拟地址空间中,那么线程就不是模型你可以使用。
  • GPU 内核启动无论如何都是异步的。只要你在调用 CPU 函数之前启动内核,并且在你的 CPU 函数之后只有 cudaMemcpy() 将结果返回给 CPU,它们无论如何都会并发运行,而根本不需要使用线程。

标签: multithreading cuda gpgpu


【解决方案1】:

正如 talonmies 所说,

将其调用放入 lambda 函数中

auto myFunc = [&](){
    cudaStream_t stream2;
    cudaSetDevice(device2); 
    cudaStreamCreate (&stream2);
    vectorAdd_gpu <<<blocksPerGrid, threadsPerBlock,0,stream2 >>>(s.a1, s.a2, s.a2, s.flag);
    cudaStreamSynchronize(stream2);
    cudaStreamDestroy(stream2);
};

然后把它交给线程。

thread t2(myFunc);
t2.join();

但除此之外,您仍然可以在 CPU 工作上异步使用应用程序的同一主线程和流。我只是展示了你想看的东西。根据工作的大小,异步使用相同的线程可能比重新创建流和重新加入线程更有效。也许重新加入比在这里同步和启动内核有更多的开销。您每秒进行多少次内核调用?

在 Nvidia 的以下博客中,https://devblogs.nvidia.com/how-overlap-data-transfers-cuda-cc/ 有一个关于单线程异步 CUDA 的好例子:

for (int i = 0; i < nStreams; ++i) {
  int offset = i * streamSize;
  cudaMemcpyAsync(&d_a[offset], &a[offset], 
                  streamBytes, cudaMemcpyHostToDevice, cudaMemcpyHostToDevice, stream[i]);
}

for (int i = 0; i < nStreams; ++i) {
  int offset = i * streamSize;
  kernel<<<streamSize/blockSize, blockSize, 0, stream[i]>>>(d_a, offset);
}

for (int i = 0; i < nStreams; ++i) {
  int offset = i * streamSize;
  cudaMemcpyAsync(&a[offset], &d_a[offset], 
                  streamBytes, cudaMemcpyDeviceToHost, cudaMemcpyDeviceToHost, stream[i]);
}

这只是进行异步流重叠的不同方法之一。

【讨论】:

  • 如何异步使用应用程序的主线程和流?仅使用一个 GPU 内核调用。
  • 我在主线程中添加了来自 nvidia 博客的示例,其中多个流用于数据复制和内核启动。
  • 谢谢@huseyin tugrul buyukisik。我会试试这个方法。
猜你喜欢
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-11
  • 1970-01-01
  • 2017-03-11
相关资源
最近更新 更多