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