std::execution::p arallel_policy 如何与 std::find 或修改容器的算法交互?

How does std::execution::parallel_policy interact with std::find or algorithms that modify the container?

提问人:Force Gaia 提问时间:7/20/2022 更新时间:7/21/2022 访问量:167

问:

我最近想起了 std::algorithm,并了解了 std::algorithm 的新执行策略,并希望在我的代码中利用它们。

我在向量上有许多循环,我正在寻找一个特定的元素(我知道它是唯一的)或与条件匹配的元素,通常以if (ele != nullptr && ele->GetID() == searchID) { /*do the thing/* }

现在我知道这看起来像是使用的主要目标,因为它找到了与该 ID 匹配的第一个元素,或者如果我正在寻找多个元素,但我担心在使用它们时可能会做什么并可能修改容器。std::find_ifstd::for_eachstd::execution::parallel_policystd::execution::parallel_unsequenced_policy

如果以某种方式,您有多个与条件匹配的元素,则应该找到第一个元素,但是如果并行执行,是否可以保证?我会总是得到第一个,而不是其他一个吗?std::find_if

如果使用 ,这将如何处理对容器的修改?我知道我需要防止数据争用,但是无论如何调用类似的东西都不会导致其他线程出现问题,因为内存中的容器会使迭代器无效吗?std::for_eachvector::erase

我知道范围是一回事,但我目前在 c++17 上,所以无法使用它们,但未来有计划。

C++ 算法 并发 C++17 标准

评论


答:

0赞 Goswin von Brederlow 7/21/2022 #1

如果您确实并行找到,则每个线程都可以搜索范围的块。然后,您不会返回任何线程找到的第一个元素,而是返回第一个线程找到的元素。除非没有找到任何东西,否则你从第二个线程返回元素。除非没有找到任何东西等等。

至于修改容器:只有当一个线程中的修改不会影响任何其他线程时,您才能使用并行执行。例如,很好。 另一方面是行不通的。你的工作是选择没有数据争用的执行策略。a[i] = a[i] * 2;a[i] = a[i - 1] + a[i - 2];

是的,我希望炸毁壮观。您必须重新设计它,以便每个线程只交换元素并返回剩余元素的范围,然后进行第二次传递以擦除所有孔。但我不知道你会怎么做.vector::erasestd::for_each