Multithreading 如何使用线程同时运行CPU和GPU功能?
我有两个我想用线程运行的函数 1) CPU函数,我可以使用以下方法将其加入线程:Multithreading 如何使用线程同时运行CPU和GPU功能?,multithreading,cuda,gpgpu,Multithreading,Cuda,Gpgpu,我有两个我想用线程运行的函数 1) CPU函数,我可以使用以下方法将其加入线程: thread t1(vector_add, p->iNum1, p->iNum2, p->iNumAns, p->flag); t1.join(); 2) 和一个GPU内核 vectorAdd\u gpu(s.a1、s.a2、s.a2、s.flag) 但我的问题是如何使用线程调用GPU内核调用并加入它,以便它可以与CPU功能同时运行 vectorAdd_gpu <<<bl
thread t1(vector_add, p->iNum1, p->iNum2, p->iNumAns, p->flag);
t1.join();
2) 和一个GPU内核
vectorAdd\u gpu(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();
vectorAdd\u gpu(s.a1、s.a2、s.a2、s.flag);
线程t2(矢量添加gpu);
t2.连接();
用线程同时运行CPU和GPU功能还有其他方法吗?正如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);
};
但与此相反,您仍然可以在CPU工作上异步使用应用程序的同一主线程和流。我只是展示了你想看的。根据工作量大小,异步使用同一线程可能比重新创建流和重新连接线程更有效。在这里,重新加入可能比同步和启动内核的开销更大。您每秒进行多少内核调用
在Nvidia的以下博客中,有一个关于单线程异步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]);
}
for(int i=0;i
这只是异步流重叠的不同方式之一。编写包装函数?这是什么语言?@AnttiHaapala:CUDA,即不是C。我不知道Jack关于GPU编程的知识,但如果GPU上运行的代码和CPU上运行的代码不在同一虚拟地址空间中运行,那么线程不是一个可以使用的模型。GPU内核启动无论如何都是异步的。只要在调用CPU函数之前启动内核,并且在CPU函数之后只有cudaMemcpy()将结果返回给CPU,它们就可以并发运行,而不需要使用线程。如何将应用程序的主线程与流异步使用?只使用了一个GPU内核调用。我添加了一个来自nvidia博客的示例,其中多个流用于主线程中的数据拷贝和内核启动。谢谢@huseyin tugrul buyukisik。我会试试这个方法。
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]);
}