CUDA контра писмо

Имам проблем с CUDA. Искам да направя малка програма, която брои букви от масив от char.

Чета букви от файл и записвам в int променлива, наречена N, колко букви са прочетени. След това аз malloc.

char *b_h, *b_d;
size_t size_char = N * sizeof(char);
b_h = (char *)malloc(size_char);

След malloc чета файла отново и присвоявам текущата буква на елемент от масива char (работи):

int j=0;
while(fscanf(file,"%c",&l)!=EOF)
{
    b_h[j]=l;
    j++;
}

След това създавам int променлива (a_h) като брояч.

int *a_h, *a_d;
size_t size_count = 1*sizeof(int);
a_h = (int *)malloc(size_count);

Добре, продължете с CUDA:

cudaMalloc((void **) &a_d, size_count);
cudaMalloc((void **) &b_d, size_char);

Копиране от хост на устройство:

cudaMemcpy(a_d, a_h, size_count, cudaMemcpyHostToDevice);
cudaMemcpy(b_d, b_h, size_char, cudaMemcpyHostToDevice);

Задаване на блокове и извикване на CUDA функция:

int block_size = 4;
int n_blocks = N/block_size + (N%block_size == 0 ? 0:1);
square_array <<< n_blocks, block_size >>> (a_d,b_d,c_d, N);

Получаване от функция:

cudaMemcpy(a_h, a_d, size_count, cudaMemcpyDeviceToHost);
cudaMemcpy(b_h, d_d, size_char, cudaMemcpyDeviceToHost);

И брой отпечатъци:

printf("\Count: %d\n", a_h[0]);

И не става. В масив от char имам изречение: Super testSuper test ; Търся буквата "e" и получих a_h[0] = 1. Къде е проблемът?

CUDA функция:

__global__ void square_array(int *a, char *b, int *c, int N)
{
const char* letter = "e";

int idx = blockIdx.x * blockDim.x + threadIdx.x;

if (idx<N) 
{
    if(b[idx] == *letter)
    {
        a[0]++;
    }
}
}

Моля, помогни ми.


person user1333885    schedule 14.04.2012    source източник
comment
Трябва да използвате atomicInc(). Вижте CUDA_C_Programming_Guide.pdf, раздел B.11.1.6 Просто проверете приложение F.1, за да сте сигурни, че имате правилната карта.   -  person Pavan Yalamanchili    schedule 16.04.2012


Отговори (1)


Предполагам, че N е достатъчно малък, за да може вашият GPU да стартира всичките ви нишки паралелно. И така, стартирате нишка за всеки знак във вашия масив. Всички нишки, работещи едновременно, не виждат изхода един от друг. Вместо това всяка нишка чете стойността на a[0] (която е 0) и я увеличава с 1 и съхранява получената стойност (1). Ако това е домашна работа, това щеше да е основният урок, който професорът искаше да предаде.

Когато множество нишки съхраняват стойност на едно и също място едновременно, не е дефинирано коя нишка ще получи съхранената стойност. Във вашия случай това няма значение, защото всички нишки, които съхраняват стойност, ще съхраняват стойността "1".

Типично решение би било всяка нишка да съхранява стойност 0 или 1 на отделно място (в зависимост от това дали има съвпадение или не) и след това да сумирате стойностите в отделна стъпка.

Можете също да използвате операция за атомно увеличаване.

person Roger Dahl    schedule 15.04.2012