我正在尝试使用CUDA解决高斯消除问题。
我有一个N*N
矩阵。要获取此矩阵的新元素,我使用下面的CPU代码,其中C.width=N
:
for(int z=0; z< C.width-1; z++)
{
for ( int c = z+1 ; c < C.width ; c++ )
{
for (int d = z ; d < C.width ; d++ )
{
C.elements[c*C.width+d]=C.elements[c*C.width+d] - (B.elements[c*C.width+z]*C.elements[z*C.width+d]);
}
}
}
我正在尝试使用CUDA实现它。例如,对于N=512
dim3 dimBlock(16,16,1);
dim3 dimGrid(32,32,1);
MatMulKernel<<<dimGrid, dimBlock>>>(d_A, d_B, d_C);
我认为对于每次迭代,我应该使用N-i*N
个线程来计算元素更新,即
if(idx>511 || idy>510)
return;
for(int i=1; i<512;i++)
{
if(idx>=i-1 && idy>=i-1)
C.elements[(idy+1)*C.width+idx]=C.elements[(idy+1)*C.width+idx]-((C.elements[(idy+1)*C.width+(i-1)]/C.elements[(i-1)*C.width+(i-1)])*C.elements[(i-1)*C.width+idx]);
__syncthreads();
}
}
在GPU和CPU上获得的结果相同,但处理时间为Time(CPU)=2*Time(GPU)
N=512
:Time(CPU) = 1900 ms
; Time(GPU) = 980 ms
N=1024
:Time(CPU) = 14000 ms
;时间(GPU)= 7766毫秒
。
。
我认为加速应该比我现在的速度更快。我的并行代码有什么错误吗?你能帮我解决一下如何重写我的代码吗?
感谢您的帮助!
答案 0 :(得分:4)
高斯消元可被视为两步程序。第一步旨在将线性系统转换为上三角线性系统,第二步包括求解如此获得的上三角线性系统。第二步在CUDA中是微不足道的,可以由cublasStrsm
有效地执行。您在帖子中提到的第一步是棘手的部分。
有几种优化方法可以解决第一步。我认为你的做法有些天真,我建议研究文献以达到体面的加速。
基本上,执行原始系统到上三角形的转换可以通过平铺方法来执行,从某些角度来看,它类似于用于执行矩阵的平铺方法 - CUDA C编程指南的经典示例中的矩阵乘法。
平铺方法可以通过特意编写的内核或大量使用cuBLAS例程来执行。
上个月(2013年11月),以下论文
Manuel Carcenac,“从瓦片算法到条带算法:基于CUBLAS的高斯GPU并行实现,用于分辨存储在固态设备阵列上的超大密集线性系统”,超级计算杂志,DOI 10.1007 / s11227-013-1043-3
提出了一种基于cuBLAS使用的平铺/剥离方法。
所有上述方法都在M. Carcenac的网页上以Application: linear system resolution with Gauss method的形式进行了总结。
此外,Gaussian elimination with CUDA帖子提供了可下载的Visual Studio 2010项目,该项目通过一些性能测试实现了所有这些项目。从可用的代码中,您可以针对您感兴趣的体系结构进行自己的测试,并体验M. Carcenac对其他方法的改进。