如何将全局内存中的数据安全地加载到 CUDA 中的共享内存中
How to load data in global memory into shared memory SAFELY in CUDA?
My kernel:
__global__ void myKernel(float * devData, float * devVec, float * devStrFac,
int Natom, int vecNo) {
extern __shared__ float sdata[];
int idx = blockIdx.x * blockDim.x + threadIdx.x;
float qx=devVec[3*idx];
float qy=devVec[3*idx+1];
float qz=devVec[3*idx+2];
__syncthreads();//sync_1
float c=0.0,s=0.0;
for (int iatom=0; iatom<Natom; iatom += blockDim.x) {
float rtx = devData[3*(iatom + threadIdx.x)];//tag_0
float rty = devData[3*(iatom + threadIdx.x)+1];
float rtz = devData[3*(iatom + threadIdx.x)+2];
__syncthreads();//sync_2
sdata[3*threadIdx.x] = rtx;//tag_1
sdata[3*threadIdx.x + 1] = rty;
sdata[3*threadIdx.x + 2] = rtz;
__syncthreads();//sync_3
int end_offset= min(blockDim.x, Natom - iatom);
for (int cur_offset=0; cur_offset<end_offset; cur_offset++) {
float rx = sdata[3*cur_offset];
float ry = sdata[3*cur_offset + 1];
float rz = sdata[3*cur_offset + 2];
//sync_4
float theta = rx*qx + ry*qy + rz*qz;
theta = theta - lrint (theta);
theta = theta * 2 * 3.1415926;//reduce theta to [-pi,pi]
float ct,st;
sincosf(theta,&st,&ct);
c += ct;
s += st;
}
}
devStrFac[idx] += c*c + s*s;
}
为什么需要标记为sync_2的"__syncthreads()"?没有sync_2,sdata[] 会得到错误的数字,我会得到错误的结果。行"tag_1"使用行"tag_0"的结果,所以在我看来sync_2没有必要。我错在哪里?如果由于指令执行混乱,我应该在"sync_4"行中加上一个__syncthreads()?
假设线程块的一个经线完成第一次迭代并开始下一次迭代,而其他经线仍在第一次迭代中工作。如果你在标签sync2
没有__syncthreads
,你最终会把这种扭曲写入共享内存,而其他人正在从该共享内存读取,这是竞争条件。
清楚起见,您可以将标签sync2
处的此__syncthreads()
移动到外部循环的末尾。
"cuda-memcheck --tool racecheck"应该告诉你问题出在哪里。
相关文章:
- 原子加载和存储与内存顺序放宽
- 如何从内存缓冲区加载张量流图
- 我在 IDA 或 dbg 或 olly 上看到的内存是否与我在 RAM 上实时加载的内存相同?
- 从C/C++(Win64)中的内存加载64位DLL
- 对外部函数的调用是否强制从内存加载
- 将使用 4 或 8 个对齐规则将加载处理到内存中
- C++:类如何将自身加载到内存中以递增全局变量?
- 加载字节数组(从内存)到libpng c
- 将内存保存到文件并加载它而不必解析数据?
- 加载时间,遍历时间,不同数据段C/C 的内存使用率
- 急切地加载整个模型以估计张量流的内存消耗
- 从内存加载动态库
- 为什么编译器在循环中从内存加载此指针
- SFML无法从内存加载图像,未提供任何数据
- 在启动时从内存加载QImages
- 在非托管程序中托管CLR时从内存加载程序集
- CImage::在不使用CreateStreamOnHGlobal的情况下从内存加载()
- 当从内存加载PNG时,Libpng错误无效的块类型
- gdkpixbuf从内存加载图像
- 从内存加载CA证书