那边发了没人理,发这边,似乎人气旺一些,请大家不吝赐教,谢谢。
我这个程序是基于蒙特卡洛算法的。不过问题不限于此,不了解这个算法的,可以只当有那么一个简单的算法就行了。
首先简单说一下蒙特卡洛算法,给不了解得人,严格地说,是我这里使用的蒙特卡洛算法,仅仅是其算法的一种应用而已。
蒙特卡洛计算是:通过对参数使用正态分布随机数处理,将处理后的结果进行运算。重复以上步骤,并统计运算后的结果出现在某个范围内的概率。
Kernel函数里:
int i=blockIdx.x*blockDim.x+threadIdx.x;//索引
float tro1=sqrtf(-2*__logf(rd1))*__cosf(2*PI*rd2)*105+1050;//rd1,rd2是内容为随机数的数组
float pi1=sqrtf(-2*__logf(rd1))*__cosf(2*PI*rd2)*513.3f*0.1f+513.3f;//以上两行的最后两个数,应该是上游函数传递的参数,为简单起见,以常数代替。
float Sigma=pi1*4.5625f*0.5f;
float L=__fdividef(powf(10,-1000*(27.1399f-4.39786f*__log10f(Sigma))),(tro1+273));
float Ft=1000*L;//每一步都是使用上一步的计算结果,最后得到Ft
if(Ft*1.25f > 1)
atomicAdd(Ni,1);//Ni为统计变量,统计Ft在给定范围内出现的次数。由于出现的可能性较小,故使用原子函数
Host端主要为建立rd1,rd2两个数组并赋值。启动Kernel,最后返回 Ni/次数(即线程数)。10次运算的平均时间大概是0.36s左右(Tesla C1060),加速比大概也有十几二十倍,记不清了。但我最初设想,因为蒙特卡洛相当于若干线程做同一件事情,最后汇总结果,所以加速比应该接近线程数。(我以前用CPU,循环手动展开,最好时也有4倍左右加速)
试过几个方法,都没有效果:分成多个流,异步传输计算;使用WriteCombined;使用Mapped(这个运行失败,硬件不支持?)
初步考虑是数据量太小?
请各位高人不吝赐教,万分感谢!
(附件,sampleStream的是用流的,sampleWCM的是用WriteCombined,sampleMapped是用Mapped的(这个我这运行不了)),由于测试,都没有用cutilSafeCall,请谅解。
有我说的不清楚的地方,请提出,谢谢
[ 本帖最后由 sailorsb 于 2010-1-13 13:33 编辑 ]