저는 CUDA 프로그래밍에 익숙하지 만 약간의 문제가 있습니다. 나는 interthread 통신이 필요한 프로그램을 작성하려고했습니다. 내가 찾은 가능한 모든 방법으로 시도했으나 여전히 작동하지 않습니다. 너는 무엇을 생각하니, 나는 무엇을 놓치고 있는가?CUDA 스레드 간 통신
아래의 코드 스 니펫은 제 전체 프로그램입니다. 매우 동일한 블록에서 2 개의 스레드를 시작합니다. 그들은 하나의 입력과 하나의 출력 배열과 다른 전역 변수를 통해 통신합니다. 값 0은 변수가 비어있어 쓰기가 가능함을 의미합니다. 기본적으로 첫 번째 요소는 입력에서 요소를 읽고 두 번째 요소로 전달하여 출력 배열에 씁니다. 나중에는 파이프 (빈) 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);
}
독자가 나타나면 사이에 더 많은 스레드와 파이프 라인, 있어야 작가 수 없습니다 변경 사항을보고 프로그램이 교착 상태가됩니다. __threadfence 및 __syncthreads를 추가하려고 시도했지만 도움이되지 않았습니다. 또한 휘발성 공유 메모리를 시도했지만 작동하지 않았습니다. 가능하다면 도와주세요. 잘 모르겠다. 무엇이 잘못되었는지.
[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)) '이어야합니다. 이것을 고치고 위에 붙여진 코드를 사용하면 효과가 있습니다. 그리고 가장 중요한 오류 검사를 잊지 마세요. –