我正在处理存储在3D数组中的大数据。这是我所做的内核示例(由CPU在for循环中调用):
attributes(global) subroutine mykernel (A,B,C,p,nx,ny,nz)
real,dimension(:,:,:),device :: A,B
real,dimension(:),device :: C
real,device :: p
integer,device :: nx,ny,nz
xInd = blockDim.x * (blockIdx.x-1) + threadIdx.x;
yInd = blockDim.y * (blockIdx.y-1) + threadIdx.y;
zInd = blockDim.z * (blockIdx.z-1) + threadIdx.z;
if (xInd<=nx) then
if (yInd<=ny) then
if (zInd<=nz) then
A(xInd,yInd,zInd)=(A(xInd,yInd+1,zInd)-A(xInd,yInd,zInd))*p-(B(xInd,yInd,zInd+1)-C(yInd)+B(xInd+1,yInd,zInd))*p+C(yInd+1)
end if
end if
end if
end subroutine mykernel
当我启动内核时,一切似乎都很好,GPU结果与CPU结果相同......但就时间而言,表现并不是很好。
我认为这是由于内存访问,但我不确定。我会把我的3D数组放在共享内存中,但我正在处理nx ny nz&gt; 1M数据,因此共享内存中没有足够的空间。
所以我的以下问题是关于表演问题,有大量数据:
答案 0 :(得分:1)
好吧所以我想我已经弄明白我的问题在我的案例中。
首先,我的内核的执行配置。使用3D数组似乎不是一个好主意,因为我使用太多线程。例如,在这里我选择使用512个线程的块。所以我用512 *(348/8 + 1)(145/8 + 1)(113/8 + 1)= 6 590 628线程调用mykernel。 如果我将我的3D数组展平为1D,我只使用512 *((348 * 145 * 113)/ 512 + 1)= 5 702 492个线程。 但为什么使用更多线程会影响我的表现?
Morover,在CPU循环中(我称之为mykernel):我在CPU和GPU之间使用了太多的传输。因此,为了减少这些传输的时间,我使用了非常有效的固定内存。我强烈建议您使用此链接获取有关how to optimize data transfers的更多解释。
通过所有这些功能,我的GPU代码比CPU代码快16倍,这非常棒!我的代码的第一个版本正在运行&#34;仅#34; x7倍。
希望它可以提供帮助。