Советы по оптимизации для кода CUDA

Я написал фрагмент кода для вычисления собственного коэффициента изображения (SQI) в MATLAB. И теперь я хочу переписать его часть параллельно для ускорения.
эта часть кода:

siz=15;
X=normalize8(X);
[a,b]=size(X);
filt = fspecial('gaussian',[siz siz],sigma);
padsize = floor(siz/2);
padX = padarray(X,[padsize, padsize],'symmetric','both');

t0 = tic; % -------------------------------------------------------------
Z=zeros(a,b);
for i=padsize+1:a+padsize
for j=padsize+1:b+padsize
region = padX(i-padsize:i+padsize, j-padsize:j+padsize);
means= mean(region(:));
M=return_step(region, means);
filt1=filt.*M;

summ=sum(sum(filt1));

filt1=(filt1/summ);
Z(i-padsize,j-padsize)=(sum(sum(filt1.*region))/(siz*siz));
end
end
toc(t0) % -------------------------------------------------------------

и функция return_step:

function M=return_step(X, means)

[a,b]=size(X);
for i=1:a
for j=1:b
if X(i,j)>=means
M(i,j)=1;
end
end
end

Я написал ниже функцию ядра:

__global__ void returnstep(const double* x, double* m, double* filt, int leng, double mean, int i, int j, int width)
{
int idx=threadIdx.y*blockDim.x+threadIdx.x;
if(idx>=leng) return;

int ridx= (j+threadIdx.y)*width+threadIdx.x+i;
double xval= x[ridx];
if (xval>=mean) m[idx]=filt[idx]*xval;
else            m[idx]=0;
}

а затем изменил код MATLAB следующим образом:

kernel= parallel.gpu.CUDAKernel('returnstep.ptx', 'returnstep.cu');
kernel.ThreadBlockSize= [double(siz) double(siz) 1];
GM = gpuArray(zeros(siz,siz));
GpadX = gpuArray(padX);
Gfilt = gpuArray(filt);

%% Process image
t0 = tic; % -------------------------------------------------------------
Z=zeros(a,b);
for i=padsize+1:a+padsize
for j=padsize+1:b+padsize
means= mean(region(:));
GM= feval(kernel, GpadX, GM, Gfilt, siz*siz, means, i-padsize-1, j-padsize-1, padXwidth);
filt1=  gather(GM);

summ=sum(sum(filt1));

filt1=(filt1/summ);
Z(i-padsize,j-padsize)=(sum(sum(filt1))/(siz*siz));
end
end
toc(t0) % -------------------------------------------------------------

мой последовательный код выполняется за 2,5 с для изображения 330X200, но время выполнения нового параллельного кода составляет 15 с. Я не знаю почему ????
Мне нужен совет для его улучшения. Я новичок в программировании CUDA.

0

Решение

> help gather
...
X = GATHER(A) when A is a GPUArray, X is an array in the local workspace
with the data transferred from the GPU device.
....

Filt1 = сбор (GM) копирует GM из GPU в CPU на каждом этапе, что очень неэффективно. Вы должны переместить все вычисления внутри гнезда цикла или, предпочтительно, всего гнезда цикла в ядро ​​графического процессора. В противном случае вы можете забыть о любом ускорении.

1

Другие решения

Моя оценка по фильтру Собеля показывает, что ЦП превосходит ГП на небольших изображениях. Я думаю, что ваш размер изображения настолько мал для сравнения производительности CPU-GPU. Вычисления должны быть достаточно большими, чтобы скрыть издержки запуска ядра и связи.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector