我有以下问题。我试图将共享数组划分为更小的数组,然后在其他设备函数中使用这些数组。在我的内核函数中,
for (int block_x = 0; block_x < blockDim.x; block_x++) {
for (int block_y = 0; block_y < blockDim.y; block_y++) {
//set up shared memory block
extern __shared__ vec3f share[];
vec3f *sh_pos = share;
vec3f *sh_velocity = &sh_pos[blockDim.x*blockDim.y];
vec3f *sh_density = &sh_velocity[blockDim.x*blockDim.y];
vec3f *sh_pressure = &sh_density[blockDim.x*blockDim.y];
//index by 2d threadidx's
unsigned int index = (block_x * blockDim.x + threadIdx.x) + blockDim.x * gridDim.x * (block_y * blockDim.y + threadIdx.y);
sh_pos[blockDim.x * threadIdx.x + threadIdx.y] = oldParticles[index].position();
sh_velocity[blockDim.x * threadIdx.x + threadIdx.y] = oldParticles[index].velocity();
sh_pressure[blockDim.x * threadIdx.x + threadIdx.y].x = oldParticles[index].pressure();
sh_density[blockDim.x * threadIdx.x + threadIdx.y].x = oldParticles[index].density();
__syncthreads();
d_force_pressure(oldParticles[arr_pos],c_kernel_support);
__syncthreads();
}
}
据我所知,所有“sh_”数组都填充了零而不是我想要的值。我不知道我做错了什么。请注意,vec3f是float的向量,就像float3数据类型一样。另外,我不认为我可以在浮子中混合密度和压力,所以我只是将它们作为矢量并使用单个组件。然后,例如我的d_force_pressure函数是,
__device__ void d_force_pressure(particle& d_particle, float h) {
extern __shared__ vec3f share[];
vec3f *sh_pos = share;
vec3f *sh_velocity = &sh_pos[blockDim.x*blockDim.y];
vec3f *sh_density = &sh_velocity[blockDim.x*blockDim.y];
vec3f *sh_pressure = &sh_density[blockDim.x*blockDim.y];
for (int i = 0; i < blockDim.x * blockDim.y; i++) {
vec3f diffPos = d_particle.position() - sh_pos[i];
d_particle.force() += GradFuncion(diffPos,h) * -1.0 * c_particle_mass * (d_particle.pressure()+sh_pressure[i].x)/(2.0*sh_density[i].x);
}
}
在调用此函数后,我得到NaN,因为我除以零(sh_density[i].x
就我所知,0)。这也是一般的,加载共享内存的正确方法吗?
内核由
调用dim3 block(BLOCK_SIZE,BLOCK_SIZE,1);
dim3 grid((int)ceil(sqrt(float(max_particles)) / (float(block.x*block.y))), (int)ceil(sqrt(float(max_particles)) / (float(block.x*block.y))), 1);
int sharedMemSize = block.x*block.y*4*sizeof(vec3f);
force_kernel<<< grid,block,sharedMemSize >>>(particle_ptrs[1],particle_ptrs[0],time_step);
答案 0 :(得分:1)
这是一个后续答案。
根据@RobertCrovella的评论,我继续运行cuda-memcheck。信不信由你,这实际上没有错误。但是,当我在代码中更改常量(控制某些数组的大小)时,cuda-memcheck显示与此处发布的问题相关的错误write error。这让我重新检查了我填充共享数组的方式。
基本上需要改变的是什么for (int block_x = 0; block_x < blockDim.x; block_x++) {
for (int block_y = 0; block_y < blockDim.y; block_y++) {
到
for (int block_x = 0; block_x < gridDim.x; block_x++) {
for (int block_y = 0; block_y < gridDim.y; block_y++) {
我相信这会为index
变量提供正确的位置。我基本上了解到,无论何时使用共享内存并注意事情运行缓慢,最好使用cuda-memcheck。
答案 1 :(得分:0)
我在上一个问题中表示你不想这样做:
dim3 grid((int)ceil(sqrt(float(max_particles)) / (float(block.x*block.y))), (int)ceil(sqrt(float(max_particles)) / (float(block.x*block.y))), 1);
你想这样做:
dim3 grid((int)ceil(sqrt(float(max_particles)) / (float(block.x))), (int)ceil(sqrt(float(max_particles)) / (float(block.y))), 1);
x网格方向应该由线程块x维度缩放,而不是线程块x维度*线程块y维度。但是我在上一个回答中发布的代码也有这个错误,即使我在评论中指出,我忘了解决它。
此外,这个索引对我来说不合适:
sh_velocity[blockDim.x * threadIdx.x + threadIdx.y]
我认为应该是:
sh_velocity[blockDim.x * threadIdx.y + threadIdx.x]
你有几个例子。
您尚未发布完整的可执行文件。肯定会有比我上面提到的问题更多的问题。如果我必须通过所有的vec3f - &gt;我在上一个问题中做过的float3转换工作,好吧,其他人可以帮助你。如果你写一个简单的复制器,它不依赖于我没有的一堆代码,我可以尝试进一步提供帮助。很可能,如果你这样做,你会自己发现问题。
您是否已将cuda错误检查放入您的代码中,就像我在上一个回答中建议的那样?
您可能还想通过cuda-memcheck运行代码:
cuda-memcheck ./mycode