Я новичок в программировании CUDA, и у меня есть проблема. Я пытался написать программу, которая требует перекрестного общения; Я пробовал это всеми возможными способами, которые я нашел, и он все еще не работает. Как вы думаете, чего мне не хватает?CUDA interthread communication
Ниже приведен фрагмент кода - моя вся программа. Он запускает 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, но это не помогло. Я также пытался использовать измененную память, но это тоже не сработало. Пожалуйста, помогите мне, если можете, потому что я понятия не имею, что с этим не так.
Попробуйте [это] (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));' Если вы исправите это и используете код, вставленный мной мной, он должен работать. И самое главное не забудьте сделать проверку ошибок. –