Эффективный и правильный способ загрузки массива с ореолом из глобальной памяти в общую
Я сталкиваюсь с проблемой загрузки массивов из глобальной памяти в общую с Hallo
Вот проблема: у меня есть большой массив (256,64) в моей глобальной памяти, который я хочу загрузить в общую память размером [16][16] В моих вычислениях мне понадобится соседнее значение (гало)
Я нахожу себя в очень расходящемся коде, таким образом, очень медленным, и в конце он не работает. Вот мой подход, я буду признателен за ваш совет
real, shared :: s_data(-1:16,-1:16)
d_j = (blockIdx%x-1) * blockDim%x + threadIdx%x-1
d_l = (blockIdx%y-1) * blockDim%y + threadIdx%y-1
tIdx = threadIdx%x -1
tIdy = threadIdx%y -1
bdimx = 256/(blockDim%x) !16
bdimy = 64/(blockDim%y) !8
d_l1=d_l+1
if(d_l1==d_lmax) d_l1=0
d_l0 = d_l -1
if(d_l==0) d_l0=d_lmax-1
call syncthreads()
!load the main part
s_data(tIdx,tIdy) = g_data(d_j,d_l)
!Filling halos
if(tIdx ==0)then
f(bx == 0) then
s_data(tIdx-1,tIdy) =0
else
s_data(tIdx-1,tIdy) = g_data(d_j-1,d_l)
end if
end if
!Fill (16,tIdy)
if(tIdx == blockDim%x-1)then
if(bx == bdmx-1) then
s_data(tIdx+1,tIdy) = 0
else
s_data(tIdx+1,tIdy) = g_data(d_j+1,d_l)
end if
end if
!Fill (-1,tIdy)
if(tIdy == 0)then
s_data(tIdx,tIdy+1)=g_data(d_j,d_l1)
end if
!Fill (N,tIdy)
if(tIdy == blockDim%y -1)then
s_data(tIdx,tIdy-1) = g_data(d_j,d_l0)
end if
!Fill (-1,-1) and (-1, N)
if(tIdx==0)then
if(bx == 0)then
if(tIdy == 0) then
s_data(tIdx-1,tIdy-1) =0
end if
if(tIdy == blockDim%y-1) then
s_data(tIdx-1,tIdy+1) = 0
end if
else
if(tIdy == 0) then
s_data(tIdx-1,tIdy-1) =g_data(d_j-1,d_l0)
end if
if(tIdy == blockDim%y) then
s_data(tIdx-1,tIdy+1) = g_data(d_j-1,d_l1)
end if
end if
end if
!Fill (N, -1) & (N,N)
if(tIdx==blockDim%x-1)then
if(bx == bdimx-1)then
if(tIdy == 0) then
s_data(tIdx+1,tIdy-1) = 0
end if
if(tIdy == blockDim%y) then
s_data(tIdx+1,tIdy+1) = 0
end if
else
if(tIdy == 0) then
s_data(tIdx+1,tIdy-1) =g_data(d_j+1,d_l0)
end if
if(dIdy == blockDim%y) then
s_data(tIdx+1,tIdy+1) = g_data(d_j+1,d_l1)
end if
end if
! сделать некоторые вычисления с s_data
1 ответ
Бокс-фильтры для обработки изображений всегда включают данные ореола. Основная идея заключается в том, что каждый выходной элемент / пиксель обрабатывается одним потоком, и каждый поток загружает более одного элемента / пикселя в общую память.
Этот документ о свертке изображения с использованием CUDA может быть хорошим справочным материалом.
http://docs.nvidia.com/cuda/samples/3_Imaging/convolutionSeparable/doc/convolutionSeparable.pdf