使用带有全局内存的同步CUDA
我正在尝试实现一个异步PSO。我的做法如下:使用带有全局内存的同步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
__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();