Memory CUDA线程间通信

Memory CUDA线程间通信,memory,cuda,communication,deadlock,pipeline,Memory,Cuda,Communication,Deadlock,Pipeline,我是CUDA编程新手,有点问题。我试图写一个程序,它需要线程间通信;我尝试了我找到的所有可能的方法,但它仍然不起作用。你觉得我错过了什么 下面的代码片段是我的整个程序。它在同一块中启动两个线程。它们获得一个输入、一个输出数组和另一个全局变量来进行通信。值0表示变量为空,因此可写。基本上,第一个从输入中读取一个元素,将值传递给第二个,第二个将其写入输出数组。后来它被认为是一个管道,在a和B之间有更多的线程 #include <cuda.h> #include <cuda_runt

我是CUDA编程新手,有点问题。我试图写一个程序,它需要线程间通信;我尝试了我找到的所有可能的方法,但它仍然不起作用。你觉得我错过了什么

下面的代码片段是我的整个程序。它在同一块中启动两个线程。它们获得一个输入、一个输出数组和另一个全局变量来进行通信。值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);

}
#包括
#包括
#包括
#定义n1
__全局无效链接(int*in,int*out,int*pipe){
int id=threadIdx.y*blockDim.x+threadIdx.x;//计算索引
如果(id==0){//writer线程

对于(int index=0;index注意,CUDA线程与POSIX线程有很大不同。它们根据单指令多线程范式(SIMT,请参阅)工作:在每个时钟周期,每个线程(在单个“包装”中)运行相同的(低级)指令

在您的代码中,写入线程将在读线程执行
NOP
s时运行,然后,第二个线程将在第一个线程执行
NOP
s时运行,但它们永远不会同时运行,因此您不会从GPU的大规模并行结构中获益

无论如何,要回答您的问题,您的
for
循环

for(int index=0;index<N;)

for(int index=0;indexTry)。执行中提到的一些错误检查总是很好的。谢谢,我会尝试这样做,但我很惊讶它也不起作用。当第一个线程到达u syncthread()时,它不是已经将所有数据传递给了第二个线程吗?但是第二个线程不会在u syncthreads()之前获取任何数据被调用,可能会再次出现死锁。或者我又错了吗?
\uu syncthread()
就像一道屏障。一个块中的所有线程都到达那里,然后继续执行。请注意下面的答案,因为它指出了一些错误(增量内部不是很好的主意,即,[index++]
中的
)。如果您确定要继续使用cuda,则需要正确理解线程、块和网格概念。还有一个错误需要指出。
cudaMemset(dev_pipe,0,1);
应该是
cudaMemset(dev_pipe,0,1*sizeof(int))
如果你解决了这个问题,并使用我上面粘贴的代码,它应该可以工作。最重要的是不要忘记做错误检查。谢谢你回答我!你是说,即使我解决了这个问题,它也会非常无效?那么在GPU上这样做不是一个好主意吗?恐怕是的。GPU是为执行数据并行任务而设计的s、 也就是说,有许多线程在许多独立的数据块上执行相同的操作。但它可以在Xeon Phi上工作。但请记住,这些加速器的工作时钟频率非常低,因此您需要最佳地利用多线程来获得性能。对于CUDA中的线程间通信,您通常应该使用共享m原子最好用于块间通信。
for(int index=0;index<N;index++)