次の問題があります。共有配列を小さな配列に分割し、これらの配列を他のデバイス機能で使用しようとしています。私のカーネル関数では、
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 は、float3 データ型と同様に float のベクトルであることに注意してください。また、密度と圧力のためにフロートを混ぜることができるとは思わなかったので、それらをベクトルにして単一のコンポーネントを使用しています。次に、たとえば、私の 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);