使用带有全局内存的同步CUDA

使用带有全局内存的同步CUDA,cuda,Cuda,我正在尝试实现一个异步PSO。我的做法如下: __global__ void particle(double *pos, double *pbest, double *vpbest, double *vel, double *gbest){ int thread = threadIdx.x + blockDim.x * blockIdx.x; int particle, i = 0; double tpbest; double l, r; int in

我正在尝试实现一个异步PSO。我的做法如下:

__global__ void particle(double *pos, double *pbest, double *vpbest, double *vel, double *gbest){

    int thread = threadIdx.x + blockDim.x * blockIdx.x;
    int particle, i = 0;
    double tpbest;

    double l, r;
    int index, best, j;

    if(thread < DIMPAR){
      particle = thread / NDIM;
        do{
            best    = ring(vpbest, &particle);

            index = (best * NDIM) + (thread % NDIM);

            l = (double) 2.05 * (double) uniform(thread) * ( pbest[thread] -   pos[thread] );
            r = (double) 2.05 * (double) uniform(thread) * ( pbest[index]  -   pos[thread] );

            vel[thread] = vel[thread] + l + r;

                pos[thread] =  pos[thread] + vel[thread];

                __syncthreads(); // I am trying wait all threads write in global memory

            if( (thread % NDIM) == 0 ){ //only one thread replace the vector
                tpbest = rastrigin(pos, particle * NDIM, NDIM);
                if(tpbest < vpbest[particle]){
                    vpbest[particle] = tpbest;
                    for(j = 0 ; j < NDIM; j++){
                        pbest[(particle * NDIM) + j] = pos[(particle * NDIM) + j];
                    }

                }
            }

            i++;
        }while(i < 10000);
    }
}
\uuuuu全局\uuuuu无效粒子(双*pos,双*pbest,双*vpbest,双*vel,双*gbest){
int thread=threadIdx.x+blockDim.x*blockIdx.x;
int粒子,i=0;
双TPP最佳;
双l,r;
int指数,最佳,j;
if(螺纹
电话:

particle<<<1,512>>>(d_pos, d_pbest, d_vpbest, d_velo, d_gbest);
粒子(d_pos,d_pbest,d_vpbest,d_velo,d_gbest);
有时同步会出现问题…pos[线程]中的某些值会出现偏差。 在第B.6节CUDA_C_编程指南中:

等待线程块中的所有线程达到此点 以及这些线程之前进行的所有全局和共享内存访问 to _syncthreads()对块中的所有线程都可见

它是这样的:

p0=[0,1,2]//粒子1

p1=[3,4,5]//粒子2

p2=[6,7,8]//粒子3

pos=[1,2,3,4,5,6,7,8]//pos向量,DIMPAR=9;NPAR=3;NDIM=3

当我使用NDIM>=30时,会发生发散

如何使用全局内存确保同步?

您的\u syncthread()if语句中。如果块大小大于DIMPAR,请小心,您的程序将停止。要使\u syncthread()正常工作,块内的所有线程都必须能够到达它

修改代码的一种方法如下(我不知道代码的用途,所以可能有更好的方法):

particle=thread/NDIM;
做{
if(螺纹
现在所有线程都可以到达同步点。
我在剩下的代码中注意到的另一个问题是,一个线程没有NDIM在for循环中工作。相反,您可以将tpbest作为共享变量(或数组)在一个块的线程之间。然后,在再次同步线程之后,您可以在已经空闲的线程之间分配NDIM工作,并使它们一起将效果写入全局内存。这样,访问速度会更快,并且可以合并。

\uSyncThreads()
保证以前对全局或共享内存的更新对块中的所有线程都可见。我不清楚为什么您将数值差异归因于
\uu syncthreads()的问题
。你怎么知道数值发散不是由你的算术产生的,就像在你的算法中一样?@RobertCrovella,谢谢。循环结束后,我在C代码(验证函数)中使用名为rastrigin的函数中的pos向量,并与vpbest[particle]进行比较值。在这一点上,值是不同的。因此,如果我始终使用相同的值,我将收到相同的值。这就像pos vector和vpbest之间存在异步…非常感谢您的帮助。在我看来,错误可能在任何地方。对于类似的问题,So期望:“有关您编写的代码问题的问题必须在问题本身中描述具体问题,并包括复制问题的有效代码。请参阅SSCCE.org以获取指导。”您尚未提供SSCCE.org代码,以及您怀疑
\uu syncthreads()的原因
函数对我来说充其量也不太清楚。投票关闭。请注意,我并不是建议您在此处转储一大堆代码。如果问题如您所述,则应该可以创建一个简单的复制器。
particle = thread / NDIM;
    do{
        if(thread < DIMPAR){
            best    = ring(vpbest, &particle);

            index = (best * NDIM) + (thread % NDIM);

            l = (double) 2.05 * (double) uniform(thread) * ( pbest[thread] -   pos[thread] );
            r = (double) 2.05 * (double) uniform(thread) * ( pbest[index]  -   pos[thread] );

            vel[thread] = vel[thread] + l + r;

            pos[thread] =  pos[thread] + vel[thread];
        }

        __syncthreads();