用户
 找回密码
 立即注册
古月 该用户已被删除
发表于 2013-4-8 17:05:39
17143
这是一个四重循环的问题,其中有两重循环放在内核函数里做,下面是第一种方法,线程的数据在内层循环汇总
for(int k=1;k<=num_threads;k++)//r圆半径对应的数 k
                        {
                                sdata1[tid]=Find1(i,j,k,tid+1)*(2*Pi/num_threads);
                                __syncthreads();
                                for(int n=num_threads/2;n>=1;n/=2)
                                {
                                        if(tid<n)
                                        {
                                       
                                                sdata1[tid]+=sdata1[tid+n];
                                        }
                                        __syncthreads();
                                }
                               
                       
                               
               
                              if(tid==0)
                            {
                                    s1+=sdata1[0]*(Rr*k/num_threads)*(Rr/num_threads);
                             }
               
                        }
                        if(tid==0)
                        {
                                *save+=s1*(2*Pi/num_threads);

                        }
                        if(tid==0&&j==num_threads)
                        {
                               
                                                *save2+=*save*(R/num_threads*i)*(R/num_threads);
                       
                       
                        }



下面是第二种方法,线程进行较多运算后再汇总数据
for(int k=1;k<=num_threads;k++)                        {                                s2+=Find1(i,j,tid+1,k)*(2*Pi/num_threads);
                        }                        sdata1[tid]=s2*(Rr*(tid+1)/num_threads)*(Rr/num_threads);                        __syncthreads();                        for(int n=num_threads/2;n>=1;n/=2)                                {                                        if(tid<n)                                        {                                                                                        sdata1[tid]+=sdata1[tid+n];                                        }                                        __syncthreads();                                }                                                        if(tid==0)                        {                                *save+=sdata1[0]*(2*Pi/num_threads);
                        }                        if(tid==0&&j==num_threads)                        {                                                                                *save2+=*save*(R/num_threads*i)*(R/num_threads);                                                                        }                       
}

个人感觉,第二种算法效率应该更高啊,他执行的同步函数的次数更少,而且汇总求和的次数也更少了,可为什么实际测试效率却更低呢?                                                                           
                       


使用道具 举报 回复
发表于 2013-4-8 18:13:55
本帖最后由 横扫千军 于 2013-4-8 18:16 编辑

我给您整理一下您的代码2,  以便其他人更好的理解您的代码(原来的太乱,看得眼花)
for(int k=1;k<=num_threads;k++)
{
        s2+=Find1(i,j,tid+1,k)*(2*Pi/num_threads);
}

sdata1[tid]=s2*(Rr*(tid+1)/num_threads)*(Rr/num_threads);
__syncthreads();

for(int n=num_threads/2;n>=1;n/=2)
{                                       
        if(tid<n)                                 
        {        
                sdata1[tid]+=sdata1[tid+n];                                       
        }               
        __syncthreads();
}

if(tid==0)
{
        *save+=sdata1[0]*(2*Pi/num_threads);
}

if(tid==0&&j==num_threads)
{        
        *save2+=*save*(R/num_threads*i)*(R/num_threads);
}
使用道具 举报 回复 支持 反对
发表于 2013-4-9 12:10:04
横扫千军 发表于 2013-4-8 18:13
我给您整理一下您的代码2,  以便其他人更好的理解您的代码(原来的太乱,看得眼花)
for(int k=1;k=1;n/=2) ...

谢谢您
使用道具 举报 回复 支持 反对
发表于 2013-4-26 17:46:48
楼主您好,因为您的问题长期没有会员、版主、NVIDIA技术支持、总版主给出现成答案,现移动到灌水专区。希望理解。
使用道具 举报 回复 支持 反对
发新帖
您需要登录后才可以回帖 登录 | 立即注册