如何避免 Cuda 争用条件,以便并行比较哈希映射中的值

How to avoid Cuda race condition, for parallel comparison of values in a hash map

提问人:Iman Fakhari 提问时间:11/11/2023 更新时间:11/17/2023 访问量:37

问:

我有一个问题,在 2D 空间 (x,y) 中,我有很多不同大小的点。带有结构体 (x,y, size) 的数组表示此空间。我想将这个空间下采样到某个特定的网格,其中 x 和 y 四舍五入到网格中最近的单元格,然后我保留单元格中的最大大小。我的想法是使用哈希图,其中我保留了从 2D 索引映射的 1D 索引,在哈希图中保留最大大小(键:1d 索引,值:最大大小),然后根据此哈希图创建输出。这是我内核中的代码,我发现其中最大尺寸:

  //nx: is the grid size in x
  //dx/dy: is the cell size in x/y
  //points: is the structure keeping the 2d points with the size as (x,y,size)
  //minBounds: has the minimum values of x and y

  int i = blockDim.x * blockIdx.x + threadIdx.x
  std::unordered_map<uint64_t, float> indexSizeMap;

  // Find point index in the grid and flatten it to 1d index
  auto xi = static_cast<uint64_t>(round((points[i].x - minBounds.x) / dx));
  auto yi = static_cast<uint64_t>(round((points[i].y - minBounds.y) / dy));
  uint64_t index1d = to1dIndex(xi, yi, nx + 1); //mapping 2d index to 1d index

  // If the index in the voxel grid is vacant, fill it. Otherwise keep the larger size
  if (indexSizeMap.count(index1d))
  {
     if (indexSizeMap[index1d] < points[i].size)
     {
        indexSizeMap[index1d] = points[i].size;
     }
  }
  else
  {
     indexSizeMap[index1d] = points[i].size;
  }

现在我发现这部分代码可能有一个竞争条件,使其具有非确定性,因为可能有两个线程同时填充同一个索引:

  if (indexSizeMap.count(index1d))
  {
     if (indexSizeMap[index1d] < points[i].size)
     {
        indexSizeMap[index1d] = points[i].size;
     }
  }
  else
  {
     indexSizeMap[index1d] = points[i].size;
  }

在查看有关竞争条件的文档时,我看到了很多处理 +/- 操作的方法,但我没有找到如何处理这种情况。在这种情况下,您是否知道避免竞争条件的方法,或者您是否建议另一种实现?

并行处理 hashmap cuda 争用条件

评论

0赞 Abator Abetor 11/11/2023
原子操作可用于实现互斥。
0赞 Abator Abetor 11/11/2023
我只需按 对点进行排序,然后按键执行最大减少,其中键是,值是index1dindex1dsize
0赞 paleonix 11/11/2023
我不确定它是否真的适合这个用例,但 NVIDIA/cuCollections 尝试实现高性能的 GPU 哈希表。
0赞 paleonix 11/11/2023
请参见 cuda::atomic_ref::fetch_max

答:

1赞 Iman Fakhari 11/17/2023 #1

解决方案是另一种实现: 由于在 Cuda 内核中使用哈希映射对我来说效果不佳,因此我最终用与我的点大小相同的数组替换了哈希图。 我把索引放在那里。第二个 CUDA 内核(即 2d)用于删除具有另一个大小更大的点的点。所以我最终会得到我需要的点。