У меня есть большой массив чисел с плавающей запятой, и я хочу узнать минимальное значение массива (игнорируя -1
, где бы оно ни было), а также его индекс, используя сокращение в CUDA. Для этого я написал следующий код, который, на мой взгляд, должен работать:
__global__ void get_min_cost(float *d_Cost,int n,int *last_block_number,int *number_in_last_block,int *d_index){
int tid = threadIdx.x;
int myid = blockDim.x * blockIdx.x + threadIdx.x;
int s;
if(result == (*last_block_number)-1){
s = (*number_in_last_block)/2;
}else{
s = 1024/2;
}
for(;s>0;s/=2){
if(myid+s>=n)
continue;
if(tid<s){
if(d_Cost[myid+s] == -1){
continue;
}else if(d_Cost[myid] == -1 && d_Cost[myid+s] != -1){
d_Cost[myid] = d_Cost[myid+s];
d_index[myid] = d_index[myid+s];
}else{
// both not -1
if(d_Cost[myid]<=d_Cost[myid+s])
continue;
else{
d_Cost[myid] = d_Cost[myid+s];
d_index[myid] = d_index[myid+s];
}
}
}
else
continue;
__syncthreads();
}
if(tid==0){
d_Cost[blockIdx.x] = d_Cost[myid];
d_index[blockIdx.x] = d_index[myid];
}
return;
}
Аргумент last_block_number
— это идентификатор последнего блока, а number_in_last_block
— количество элементов в последнем блоке (степень 2
). Таким образом, все блоки каждый раз будут запускать 1024
потоков, а последний блок будет использовать только number_in_last_block
потоков, а остальные будут использовать 1024
потоков.
После запуска этой функции я ожидаю, что минимальные значения для каждого блока будут в d_Cost[blockIdx.x]
, а их индексы в d_index[blockIdx.x]
.
Я вызываю эту функцию несколько раз, каждый раз обновляя количество потоков и блоков. Во второй раз, когда я вызываю эту функцию, количество потоков теперь становится равным количеству оставшихся блоков и т. д.
Однако вышеуказанная функция не дает мне желаемого результата. На самом деле, каждый раз, когда я запускаю программу, она выдает разные результаты, т. е. возвращает неправильное значение как минимум на какой-то промежуточной итерации (хотя это неверное значение каждый раз довольно близко к минимуму).
Что я здесь делаю неправильно?
__syncthreads()
в цикле for из-за операторов continue. Это намеренно? Это, вероятно, не будет делать то, что вы хотите. - person Heatsink   schedule 31.03.2014