CUDA подсчет, сокращение и перекос нитей - PullRequest
1 голос
/ 15 октября 2010

Я пытаюсь создать программу cuda, которая подсчитывает количество истинных значений (определенных ненулевыми значениями) в длинном векторе с помощью алгоритма редукции.Я получаю забавные результаты.Я получаю либо 0, либо (ceil (N / threadsPerBlock) * threadsPerBlock), ни то, ни другое не верно.

__global__ void count_reduce_logical(int *  l, int * cntl, int N){
    // suml is assumed to blockDim.x long and hold the partial counts
    __shared__ int cache[threadsPerBlock];
    int cidx = threadIdx.x;
    int tid = threadIdx.x + blockIdx.x*blockDim.x;

    int cnt_tmp=0;
    while(tid<N){
        if(l[tid]!=0)
                cnt_tmp++;
        tid+=blockDim.x*gridDim.x;
    }
    cache[cidx]=cnt_tmp;
    __syncthreads();
    //reduce
    int k =blockDim.x/2;
    while(k!=0){
        if(threadIdx.x<k)
            cache[cidx] += cache[cidx];
        __syncthreads();
        k/=2;
    }
    if(cidx==0)
        cntl[blockIdx.x] = cache[0];
}

Затем хост-код собирает результаты cntl и завершает суммированиеЭто будет частью более крупного проекта, в котором данные уже находятся на графическом процессоре, поэтому имеет смысл выполнять вычисления там, если они работают правильно.

Ответы [ 2 ]

2 голосов
/ 15 октября 2010

Вы можете считать ненулевые значения с помощью одной строки кода, используя Тяга .Вот фрагмент кода, который подсчитывает количество единиц в device_vector.

#include <thrust/count.h>
#include <thrust/device_vector.h>
...
// put three 1s in a device_vector
thrust::device_vector<int> vec(5,0);
vec[1] = 1;
vec[3] = 1;
vec[4] = 1;

// count the 1s
int result = thrust::count(vec.begin(), vec.end(), 1);
// result == 3

Если ваши данные не находятся внутри device_vector, вы все равно можете использовать thrust::count с помощью , оборачивая необработанныеуказатели .

1 голос
/ 15 октября 2010

В вашем сокращении вы делаете:

cache[cidx] += cache[cidx];

Разве вы не хотите тыкать в другую половину локальных значений блока?

...