首页 文章

如何使用线程同时运行CPU和GPU功能?

提问于
浏览
-2

我有两个函数,我想使用线程运行 .

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功能的任何其他方式?

1 回答

  • 0

    正如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]);
    }
    

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

相关问题