Встречное письмо CUDA

У меня проблема с CUDA. Я хочу сделать небольшую программу, которая считает буквы из массива символов.

Я читаю буквы из файла и сохраняю в переменную int с именем N, сколько букв прочитано. После этого я malloc.

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

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

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 достаточно мал, чтобы ваш графический процессор мог запускать все ваши потоки параллельно. Итак, вы запускаете поток для каждого символа в вашем массиве. Потоки, работающие одновременно, не видят выходных данных друг друга. Вместо этого каждый поток считывает значение a[0] (которое равно 0), увеличивает его на 1 и сохраняет полученное значение (1). Если это домашнее задание, то это был бы основной урок, который хотел преподать профессор.

Когда несколько потоков одновременно сохраняют значение в одном и том же месте, неизвестно, какой поток получит сохраненное значение. В вашем случае это не имеет значения, потому что все потоки, хранящие значение, будут хранить значение «1».

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

Вы также можете использовать операцию атомарного увеличения.

person Roger Dahl    schedule 15.04.2012