这是一段用SAS写的程序,现在想并行加速,但是比较烦的是vi是一直在更新的,而且s0也随vk[j]而变化,所以我现在想不到好的办法能让k组数据同时并行运算,想请各位帮帮忙~
do j=1 to k;
s0=vk[j];
zvz=z[,j]*vi*z[,j]; //z[,j]表示矩阵的第j列,z[,j]
表示z[,j]的转置
yvz=r*vi*z[,j]; dum=max((yvz**2-zvz)/zvz**2+s0,1e-30); vk[j]=dum; v = v + z[,j]*z[,j]
*(vk[j]-s0);
vi=inv(v);
end;
简要地看了下文中代码/伪码,虽然每次循环中其实只和j有关,但是应该是随着循环逐次更新的,这似乎不能直接将关于j的循环直接展开为k次。
建议考虑下,一次循环内,这些计算能否细粒度地并行计算。
欢迎莅临cudazone,祝您编码愉快。
就是说一次循环内像矩阵相乘这样的并行?还有一个问题就是我在Kernel函数里可不可以调用cublas库或者是cula库里面的函数?
1:是的
2:我不懂此两个库,请参阅相关文档或留待其他人补充。
祝您编码愉快。
各位高手帮个忙啊,周末就要汇报了,我实在是想破了脑袋都不知道该怎么并行,如果说像ice说的细粒度并行的话,我估计加速不会明显,真的没有办法并行吗?老板是搞统计学的,他不懂计算机,他非说可以并行,哎。。。!
K的规模是多少?
模拟数据是961,实际上可能达到5000,如果算上位性的话,会达到5000*(5000-1)/2的规模!
我们实验室购买了正版的SAS 9.3软件,算上位性的话,5000个样本961个标记,用我的i5 2400, 8G 内存,64位WIN7操作系统要算3天多才能算完!所以想用CUDA来加速~
既然老板说了能并行,最好请教老板啊。
具体算法你不清楚,可以弄明白就好了。
可能是数据依赖关系搞清楚就能并行了,也许。
因为细节一时难以弄清楚,我也感觉还是细粒度并行比较好。但K规模太大,矩阵数组太小效率会差。
老板就不懂编程,因为浙江大学朱军教授基于混合先行模型的算法已经写成GPU并行软件,老板想我们的模型也编成GPU加速的并行软件,因为是搞统计的,我们实验室的算法都是用SAS和R语言写的,我习惯先把它们写成C,再改写成CUDA C,这个算法里面唯一加速的就是矩阵求逆,调用的是CULA包里面的函数,用小数据来测试(100*50),时间由原来的116s左右提高到22s左右,加速还是有的,我想如果把K个标记同时运算,那样加速肯定明显。
如果您关于j从1到k的循环里面是某种迭代过程,那应该很难改为并行的,因为本次结果依赖上次结果。
如果该过程仅为某种标记,您可以试图将他们并行,并维护多个标记结果,最后再处理。当然这需要您的算法真的允许这样。
无法给出进一步的建议了。
祝您编码愉快。
没有仔细阅读您的代码。也不是很懂SAS,只懂C,C++。如果讨论,最好能注释,不然就是空谈。
另外支持版主意见,细粒度并行本来就是CUDA的擅长。
好的,我在看看吧,太纠结了,实验室就我一个人搞这个方向,老板也不懂,孤军奋战啊!!!
这是上面这段SAS代码的C语言翻译版,我再发一个帖子吧,大家帮我参谋一下,因为考虑到老板要发文章的问题,整个程序的代码不方便全部发上来,只发需要并行的一部分代码,这段代码搞懂了,其他的我也就明白了,因为下面几段代码都是这个模式的。
for(int j=0;j<XCOL;j++) //start update main effect QTL variance
{
for(int ione=0;ione<XROWXROW;ione++)
{
VItemp1[ione]=VI[ione];
}
s0=VK[j];
double ZVZ=0.0;
double YVZ=0.0;
double ZTVI[XROW];
for(int i=0;i<XROW;i++)
{
ZTVI[i]=0.0;
}
for(int i=0;i<XROW;i++)
{
for(int k=0;k<XROW;k++)
{
ZTVI[i]=ZTVI[i]+XMatrix[j+kXCOL]*VI[i+k*XROW];
}
}
for(int i=0;i<XROW;i++)
{
ZVZ=ZVZ+ZTVI[i]XMatrix[j+iXCOL];
}
for(int i=0;i<XROW;i++)
{
RTVI[i]=0.0;
}
for(int i=0;i<XROW;i++)
{
for(int k=0;k<XROW;k++)
{
RTVI[i]=RTVI[i]+R[k]*VI[i+k*XROW];
}
}
for(int i=0;i<XROW;i++)
{
YVZ=YVZ+RTVI[i]XMatrix[j+iXCOL];
}
double dum=0.0; //using explicit algorithm
dum=Maxmium((YVZ*YVZ-ZVZ)/(ZVZ*ZVZ)+s0,1e-30);
VK[j]=dum;
for(int i=0;i<XROW;i++)
{
for(int k=0;k<XROW;k++)
{
V[i*XROW+k]=V[i*XROW+k]+XMatrix[i*XCOL+j]*XMatrix[k*XCOL+j]*(VK[j]-s0);
}
}
for(int i=0;i<XROW*XROW;i++)
{
VI[i]=V[i];
}
if((VK[j]-s0)!=0)
{
inverse(VI,XROW);
for(int ione=0;ione<XROW*XROW;ione++)
{
VItemp1[ione]=VI[ione];
}
}
else
{
for(int ione=0;ione<XROW*XROW;ione++)
{
VI[ione]=VItemp1[ione];
}
}
} //end update main effect QTL variance
代码太长,我再看看吧。
嗯,好的。应你的要求我又发了一个帖子,那里面我都注释了,你可以看看。我在想如果细粒度的并行能够加速10吗?
zvz=z[,j]*vi*z[,j]; //z[,j]表示矩阵的第j列,z[,j]
表示z[,j]的转置
yvz=r`viz[,j];
简单分析了一下,好像的确不能对J并行,但是如上两句向量,矩阵计算好像是可以并行的。
- 确实不能整体并行。
- 加速比感觉上应该可以提高很多的。不知道你的矩阵行大小。
如果行列都比较大加速10倍是可能的啊。
放心做吧,不止加速10倍。