提问人:Iman Fakhari 提问时间:11/11/2023 更新时间:11/17/2023 访问量:37
如何避免 Cuda 争用条件,以便并行比较哈希映射中的值
How to avoid Cuda race condition, for parallel comparison of values in a hash map
问:
我有一个问题,在 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;
}
在查看有关竞争条件的文档时,我看到了很多处理 +/- 操作的方法,但我没有找到如何处理这种情况。在这种情况下,您是否知道避免竞争条件的方法,或者您是否建议另一种实现?
答:
1赞
Iman Fakhari
11/17/2023
#1
解决方案是另一种实现: 由于在 Cuda 内核中使用哈希映射对我来说效果不佳,因此我最终用与我的点大小相同的数组替换了哈希图。 我把索引放在那里。第二个 CUDA 内核(即 2d)用于删除具有另一个大小更大的点的点。所以我最终会得到我需要的点。
评论
index1d
index1d
size
cuda::atomic_ref::fetch_max
。