Я написал код в CUDA C, но по какой-то причине я не могу объяснить, что он работает неправильно, возможно, кто-то может увидеть, что я делаю неправильно, или, возможно, это ошибка.
Код:
#include <iostream>
#define N 1000000
__global__ void kernel( int *a, int *b ){
int i=threadIdx.x+blockIdx.x*blockDim.x;
int j;
int count;
while(i<N){
count=0;
for(j=0;j<N;j++){
if(b[i]>b[j]){
count++;
}
}
a[i]=count;
i+=blockDim.x*gridDim.x;
}
}
int main (void) {
int i;
int *a,*b;
int *d_a,*d_b;
int size=N*sizeof(int);
srand( 1234 );
//setup input values
a = (int*)malloc(size);
for(i=0;i<N;i++) a[i]=5;
b = (int*)malloc(size);
for(i=0;i<N;i++) b[i]=rand()%N;
//alloc device memory
cudaMalloc((void**)&d_a, size );
cudaMalloc((void**)&d_b, size );
//copy to device
cudaMemcpy( d_b, b, size, cudaMemcpyHostToDevice );
//run kernel
kernel<<< 1, 128 >>>( d_a, d_b);
//copy to host
cudaMemcpy( a, d_a, size, cudaMemcpyDeviceToHost );
//print a
for(i=0;i<10;i++) std::cout << a[i] << " ";
std::cout << "\n";
//Cleanup
free(a);
free(b);
cudaFree(d_b);
cudaFree(d_a);
return 0;
}
Должен подсчитываться каждый элемент массива b (d_b), чтобы узнать номера других элементов b (d_b), которые меньше этого элемента и установлены в массив a (d_a). ). Затем он записывает первые 10 элементов (d_a) для проверки правильности.
Но когда я компилирую и запускаю, он замораживает всю систему на 30 секунд и печатает:
5 5 5 5 5 5 5 5 5 5
, т. Е. A имеет свои начальные значения. Я сделал некоторый тест:
1) Если я установлю N на 10 ^ 5 вместо 10 ^ 6, это будет работать так, как должно. Но это не проблема памяти, я запускаю много других кодов с большими массивами, и это не показывает никаких проблем;
2) Если я закомментирую строку
a[i]=count;
, она будет работать нормально (но не правильно). То же самое происходит, если я комментирую строку,
count++;
Может кто-нибудь сказать мне, что я делаю неправильно?
Моя система:
Ubuntu 19.10
Geforce GTX 970
Драйвер NVIDIA 435.21
Инструменты для компиляции Cuda, выпуск 10.1, V10.1.168