2016-06-03 3 views
0

Я пытаюсь реализовать довольно простое усреднение во время преобразования изображения. Я уже успешно реализовал преобразование, но теперь мне нужно обработать это результирующее изображение, суммируя все пиксели всех прямоугольников 5x5 пикселей. Моя идея заключалась в том, чтобы увеличивать счетчик для каждого такого блока 5x5 всякий раз, когда установлен пиксель в этом блоке. Тем не менее, эти блок-счетчики значительно не увеличиваются. Таким образом, для отладки я проверил, как часто любой пиксель такого блока попал на все:Координаты CUDA:

int x = (blockIdx.x*blockDim.x) + threadIdx.x; 
    int y = (blockIdx.y*blockDim.y) + threadIdx.y; 

    if((x<5)&&(y<5)) 
{ 
    resultArray [0]++; 
} 

Ядро называется так:

dim3 threadsPerBlock(8, 8); 
dim3 grid(targetAreaRect_px._uiWidth/threadsPerBlock.x, targetAreaRect_px._uiHeight/threadsPerBlock.y); 
CudaTransformAndAverageImage << < grid, threadsPerBlock >> > (pcPreRasteredImage_dyn, resultArray); 

Я ожидал бы resultArray [0] содержит 25 после ядро, но оно содержит только 1. Это связано с некоторой оптимизацией компилятором CUDA?

+0

Ядро вызывается следующим образом: dim3 threadsPerBlock (8, 8); сетка dim3 (targetAreaRect_px._uiWidth/threadsPerBlock.x, targetAreaRect_px._uiHeight/threadsPerBlock.y); CudaTransformAndAverageImage << >> (pcPreRasteredImage_dyn, resultArray); – juergen861

ответ

2

Это:

if((x<5)&&(y<5)) 
{ 
    resultArray [0]++; 
} 

для чтения после записи опасности.

Все потоки, которые удовлетворяют (x<5)&&(y<5), могут пытаться одновременно считывать и записывать от resultArray[0]. Модель исполнения CUDA не гарантирует ничего о порядке одновременных транзакций памяти.

Вы могли бы сделать эту работу с помощью атомарных транзакций памяти, например:

if((x<5)&&(y<5)) { 
    atomicAdd(&resultArray[0], 1); 
} 

Это сериализации транзакций памяти и сделать расчет правильный. Это также будет иметь большое негативное влияние на производительность.

Возможно, вам захочется исследовать, что каждый блок вычисляет локальную сумму с использованием вычисления типа сокращения, а затем суммирует локальные суммы блока атомарно или на хосте или во втором ядре.

+0

Большое вам спасибо за ваш совет! Это действительно спасло день для новичка CUDA! :-) – juergen861

Смежные вопросы