我试图比较使用FFT与使用窗口方法的互相关。
我的Matlab代码是:
isize = 20;
n = 7;
for i = 1:n %%7x7 xcorr
for j = 1:n
xcout(i,j) = sum(sum(ffcorr1 .* ref(i:i+isize-1,j:j+isize-1))); %%ref is 676 element array and ffcorr1 is a 400 element array
end
end
类似的CUDA内核:
__global__ void xc_corr(double* in_im, double* ref_im, int pix3, int isize, int n, double* out1, double* temp1, double* sum_temp1)
{
int p = blockIdx.x * blockDim.x + threadIdx.x;
int q = 0;
int i = 0;
int j = 0;
int summ = 0;
for(i = 0; i < n; ++i)
{
for(j = 0; j < n; ++j)
{
summ = 0; //force update
for(p = 0; p < pix1; ++p)
{
for(q = 0; q < pix1; ++q)
{
temp1[((i*n+j)*pix1*pix1)+p*pix1+q] = in_im[p*pix1+q] * ref_im[(p+i)*pix1+(q+j)];
sum_temp1[((i*n+j)*pix1*pix1)+p*pix1+q] += temp1[((i*n+j)*pix1*pix1)+p*pix1+q];
out1[i*n+j] = sum_temp1[((i*n+j)*pix1*pix1)+p*pix1+q];
}
}
}
}
我在我的内核中将其称为
int blocksize = 64; //multiple of 32
int nblocks = (pix3+blocksize-1)/blocksize; //round to max pix3 = 400
xc_corr <<< nblocks,blocksize >>> (ffcorr1, ref_d, pix3, isize, npix, xcout, xc_partial);
cudaThreadSynchronize();
不知何故,当我在输出文件上执行diff时,我发现CUDA内核只计算前400个元素。
编写这个内核的正确方法是什么?
另外,在我的内核中声明i,j的区别是什么?
int i = blockIdx.x * blockDim.y + threadIdx.x * threadIdx.y;
int j = blockIdx.y * blockDim.x + threadIdx.x * threadIdx.y;
答案 0 :(得分:4)
int blocksize = 64; //multiple of 32
int nblocks = (pix3+blocksize-1)/blocksize; //round to max pix3 = 400
xc_corr <<< nblocks,blocksize >>> (ffcorr1, ref_d, pix3, isize, npix, xcout, xc_partial);
意味着每个块启动64个线程,并且线程块的数量等于处理pix3元素所需的数量。如果pix3确实是400,那么你正在处理400个元素,因为你将启动7个线程块,每个线程块有64个点,其中48个没有做任何事情。
我不太确定这里的问题是什么。
另外,
int i = blockIdx.x * blockDim.y + threadIdx.x * threadIdx.y;
int j = blockIdx.y * blockDim.x + threadIdx.x * threadIdx.y;
blocksize和nblocks实际上被转换为dim3向量,因此它们具有(x,y,z)值。如果您使用&lt;&lt;&lt; 64,7&gt;&gt;调用内核,则会将其翻译为
dim3 blocksize(64,1,1);
dim3 nblocks(7,1,1);
kernel<<blocksize,nblocks>>();
因此对于每个内核调用,blockIdx都有3个组件,即线程id x,y和z,对应于你所在线程的3d网格。在你的情况下,因为你只有一个x组件blockIdx。无论如何,y和threadIdx.y都将为1。基本上,它们没用。
老实说,您似乎应该从用户手册中重读CUDA的基础知识,因为您似乎缺少许多基础知识。在这里解释它不经济since it's all written down in a nice documentation you can get here。如果您只想使用cuda进行更快的FFT,那么您可以在Nvidia的CUDA区域下载并安装许多库,如果您不关心学习CUDA,它将为您完成。
祝你好运。
PS。你不需要在每个内核之后调用cudaThreadSynchronize;)