vtkUnstructuredGrid->GetPoint() 的线程安全只读替代方案

Thread-safe read-only alternative to vtkUnstructuredGrid->GetPoint()

我已经开始研究多线程和点云处理。问题是我必须在现有的实现上实现多线程,并且有太多的读写操作,所以使用互斥体不能给我足够的性能加速,因为来自 grid 的读取操作太多了。

最后我修改了代码,这样我就可以拥有一个 vtkSmartPointer<vtkUnstructuredGrid> 来保存我的点云。线程必须做的唯一操作是使用 GetPoint 方法访问点。但是,由于智能指针,即使您有只读操作,它也不是线程安全的。

因此,我必须为每个线程复制我的主要点云,如果我有太多线程和大云,最后会导致内存问题。

我试图将点云切割成块,但是当我有太多线程时它又变得太复杂了。我不能保证优化每个线程要处理的点数。此外,我对每个点进行邻域搜索,因此将点云切割成块变得更加复杂,因为我需要对每个块进行重叠以获得正确的邻域搜索。

由于vtkUnstructuredGrid是内存优化的,我无法用一些STL容器替换它。如果您能向我推荐可用于线程安全读取的点云处理的数据结构,我会很高兴。或者如果有任何其他解决方案我可以使用。

提前致谢

我不熟悉 VTK 或它的工作原理。

总的来说,在多线程环境中有多种技术和方法可以提高性能。问题比较模糊,只能笼统的回答一下。

  • 简单:如果读多写少,使用std::shared_mutex,因为它允许同时读取多个。
  • 中等:如果线程大部分时间处理不同的数据:它们访问相同的数据数组但位于不同的位置 - 那么您可以实现一个处理程序来确保线程同时处理不同的数据片段而没有交集,如果线程要求处理当前正在处理的数据片段,则告诉它处理其他数据或等待。
  • Hard:有些方法可以通过 std::atomic 利用各种内存指令实现高效并发。我不太熟悉它,它绝对不简单,但你可以在互联网上寻找它的教程。据我所知,此类方法的某些部分仍在研发中,尚未开发出最佳实践。

P.S. 如果同一数据有很多 reads/writes... 实现是否意识到数据是共享的在几个线程上?它甚至可以正确执行吗?您可能最终需要重写整个实现。

我只是想 post 解决方案,因为它实际上是我的愚蠢。我意识到在我的代码的一部分,我使用的是 GetPoint()double* vtkDataSet::GetPoint(vtkIdType ptId) 版本,它不是线程安全的。

对于多线程代码,应该使用 void vtkDataSet::GetPoint(vtkIdType id,double x[3])