我是CUDA编程的新手,我有点问题。我试图编写一个需要线程间通信的程序;我尝试了我找到的各种可能的方式,但仍然无法正常工作。你怎么看,我错过了什么?CUDA线程通信
下面的代码片段是我的整个程序。它在同一个块中启动2个线程。他们得到一个输入,一个输出数组,以及另一个全局变量来通信。值0表示该变量为空,因此可写。基本上,第一个从输入读取元素,将值传递给第二个元素,将其写入输出数组中。后来,它应该是一个管道,A和B.
#include <cuda.h>
#include <cuda_runtime.h>
#include <stdio.h>
#define N 1
__global__ void link(int *in, int *out, int *pipe){
int id = threadIdx.y*blockDim.x + threadIdx.x; //compute index
if(id == 0){ //writer thread
for(int index = 0;index<N;){
if(pipe[0]==0){
atomicExch(pipe, in[index++]);
}
}
}
else if(id == 1){ // reader thread
for(int index=0;index<N;) {
if(pipe[0]!=0){
out[index++] = atomicExch(pipe, 0); //read and make it empty
}
}
}
}
int main(){
int input[] = {8,7};
int *dev_input;
int *dev_output;
int *dev_pipe;
int *output = (int*) malloc (N*sizeof(int));
cudaMalloc((void**) &dev_input, N*sizeof(int));
cudaMalloc((void**) &dev_output, N*sizeof(int));
cudaMalloc((void**) &dev_pipe, 1*sizeof(int));
cudaMemset(dev_pipe, 0, 1);
cudaMemcpy(dev_input, &input[0], N*sizeof(int), cudaMemcpyHostToDevice);
link<<<1, 2>>>(dev_input, dev_output, dev_pipe);
cudaMemcpy(output, dev_output, N*sizeof(int), cudaMemcpyDeviceToHost);
printf("[%d", output[0]);
for(int i = 1;i<N;i++)
printf(", %d", output[i]);
printf("]\n");
int d = 0;
scanf("\n", &d);
}
如果读者看到之间更多的线程,该管道是0(空),提出的第一个元素就可以了,但笔者不能看到任何更改,程序进入僵局。我试图添加__threadfence和__syncthreads,但它没有帮助。我也尝试了volatile共享内存,但它也没有工作。请帮助我,如果可以的话,因为我不知道,它有什么问题。
请尝试[this](http://pastebin.com/mSAZm86S)。此外它总是很好做一些错误检查中提到[这里](http://stackoverflow.com/questions/14038589/what-is-the-canonical-way-to-check-for-errors-using-the-cuda -runtime-API)。 –
谢谢,我会试试这个,但我担心它也不行。当第一个线程到达__syncthread()时它不会将所有数据传递给第二个线程?但是在调用__syncthreads()之前,第二个函数不会接受它们中的任何一个,所以它可能再次成为死锁。或者我又想错了? – user3017074
'__syncthread()'就像一个障碍。块中的所有线程都会到达那里,然后继续执行。请注意下面的答案,因为它指出了一些错误(增加内部不是很好的想法,即''在[index ++]')。如果您确定要继续使用cuda,那么您需要正确理解线程,块和网格概念。还有一个错误需要指出。 'cudaMemset(dev_pipe,0,1);'应该是'cudaMemset(dev_pipe,0,1 * sizeof(int));'如果你修复这个问题并使用上面粘贴的代码,它应该可以工作。最重要的是不要忘记进行错误检查。 –