簡體   English   中英

CUDA在單個內核中多個動態分配的共享陣列

[英]CUDA multiple dynamically allocated shared arrays in single kernel

我有以下問題。 我試圖將共享數組分成較小的數組,然后在其他設備功能中使用這些數組。 在我的內核函數中,

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);
  }  
 }

調用此函數后,由於我被零除( sh_density[i].x據我所知為0),因此得到NaN。 同樣,這也是加載共享內存的正確方法嗎?

內核由

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);

這是一種后續答案。

根據@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是一個好主意。

我在您先前的問題中指出您不想這樣做:

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-> float3轉換工作,那么其他人可以為您提供幫助。 如果您編寫的簡單復制器不依賴我沒有的一堆代碼,那么我可以嘗試進一步提供幫助。 如果您這樣做,很有可能自己發現問題。

您是否像我在上一個答案中所建議的那樣將cuda錯誤檢查放入代碼中?

您可能還想通過cuda-memcheck運行代碼:

cuda-memcheck ./mycode

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM