可以从并行线程完成对 boost 的 rtree 的查询吗?

Can queries to boost's rtree be done from parallel threads?

我有两个模块在申请中。 Module1 拥有并构建 boost::geometry::index::rtreeModule2Module1 进行查询,这些查询将传递给 RTree。现在我想加快速度并拥有多个 Module2 实例,它们对 one Module1 实例进行查询,并单独工作。我 100% 确定,尽管 任何模块 2 工作 RTree 都不会改变

我发现了这个问题:,但它描述了更复杂的情况,当从不同线程修改和查询 rtree 时。这个答案是模棱两可的: "No boost Rtree is not thread-safe in any way" 在答案中陈述。但在评论中指出:"It is safe to do queries, and it even possible to create workaround for creation"。什么是正确答案?除了直接提问以提升作者外,是否有任何资源可供查找?

Tl;博士:

从不同的线程向 boost::geometry::index::rtree 查询是否安全,如果我 100% 确定没有线程修改 RTree?

In answer to linked question: "No boost Rtree is not thread-safe in any way". But in comments: "It is safe to do queries, and it even possible to create workaround for creation". Who is right?

没有矛盾。亚当是作者。每个人都是对的。注意答案也说了

You /can/ run multiple read-only operations in parallel. Usually, library containers are safe to use from multiple threads for read-only operations (although you might want to do a quick scan for any mutable members hidden (in the implementation).

一般来说,只要按位表示不发生变化,并发访问 一切都是安全的。这与库支持无关。

请注意,由于 Adam Wulkiewicz 的权威评论,您不需要“快速扫描”。


脚注:这仍然不能使库线程安全。这是真的,因为 C++ 的内存模型不存在按位常量数据的数据竞争。

这似乎不是完整的问题。我正在阅读的内容分为两部分。第一部分应该是“我想优化我的程序。我应该怎么做?”

您应该在优化之前使用分析器进行测量!您可能会注意到在这个过程中有更多重要的优化可供您使用,并且这些优化可能会被排除在外如果您过早地引入多线程,那么 window 的可能性。

您应该在优化后使用分析器进行测量!发现优化无关紧要的情况并不少见。在多线程优化方面,从您的测量中您应该看到处理 一个任务 需要 稍微长一些 但是您可以处理 在具有四核 CPU 的计算机上一次 四和八。如果 稍微长一点 等于 4-8 倍,那么显然多线程是不必要的膨胀引入而不是优化。

第二部分,你提供的,以这两条语句的形式:

I am 100% sure, that while any Module2 working RTree does not change.

Is it safe to make queries to boost::geometry::index::rtree from different threads, if I am 100% sure, that no thread modifies RTree?

你应该使用锁。如果不这样做,您将调用未定义的行为。我将解释为什么您稍后应该使用锁。

我建议对您描述的用例使用 read/write 锁(例如 pthread_rwlock_t)。 这将允许您的线程访问资源只要没有线程尝试写入,就可以同时进行,并为将更新推送到线程提供围栏。

为什么要使用锁? 首先,它们保证您的代码能够正常运行;任何关于它是否安全的担忧都将无效。其次,锁提供了一个可以将更新推送到线程的栅栏;与您应该从中看到的增益量相比,任何关于性能影响的问题 都可以忽略不计

您应该在每个线程中执行多个任务! 这就是栅栏很重要的原因。如果您的线程最终终止,而您稍后又创建了新的线程,那么您将产生开销,这在执行优化时当然是不受欢迎的。如果一个线程终止,尽管稍后预见到更多这些任务,那么该线程可能应该被挂起。

预计您的优化可能会变成窃取工作的线程池。当我们瞄准最重要的优化时,这就是优化的本质。有时它是迄今为止最重要的,或者毕竟是 瓶颈。优化此类瓶颈可能需要采取极端措施。

我之前强调了“应该可以忽略不计”,因为您只能在一定程度上看到性能的显着提高;尝试在具有 4 个内核(每个内核 2500 个线程)的处理器上启动 10000 个线程(每个线程占用 0.5 到 4.0MB 堆栈 space,总共 5-40GB)应该是有意义的是非常理想的。尽管如此,这是许多人出错的地方,如果他们有一个分析器指导他们,他们将更有可能注意到...

如果您的任务涉及可以成为非阻塞的 IO,您甚至可以在一个线程上完成 运行 多个任务。这通常是我在研究多线程之前会研究的优化,因为分析器会突出显示。