【问题标题】:How to iterate through a directory_iterator in parallel?如何并行遍历 directory_iterator?
【发布时间】:2022-01-18 15:04:59
【问题描述】:

std::filesystem::directory_iterator 是一个LegacyInputIterator,显然它不能并行使用std::for_each

我可以遍历directory_iterator,获取项目,将它们放在一个向量中,然后使用该向量进行并行迭代。

上面的步骤可以省略吗?有没有办法像这样并行遍历directory_iterator

std::for_each(
    std::execution::par_unseq, // This is ignored currently
    std::filesystem::begin(dir_it),
    std::filesystem::end(dir_it),
    func
);

【问题讨论】:

  • std::foreach() 只能在迭代器满足LegacyForwardIterator 的要求时与并行执行策略一起使用。 LegacyInputIterator 不符合条件 - 因此不能用于多通道或并行算法。实际上,这是因为在大多数现实世界的系统上遍历目录是在一个方向上发生的(即从第一个条目迭代到最后一个条目,但不会在目录条目中来回迭代),因此可以轻松实现目录迭代器以满足 @987654330 的要求@但不是LegacyForwardIterator的要求

标签: c++ parallel-processing


【解决方案1】:

directory_iterator 是一个输入迭代器,这意味着它在遍历期间生成值。此外,对同一目录的多次遍历可能会产生不同的值序列(就顺序和值本身而言),这意味着遍历不可重新启动。

对于并行算法,这意味着不能对序列进行分区,迭代必须在一个线程中按顺序进行。并行化处理的唯一机会是将func 执行卸载到单独的线程,这可能有效也可能无效。文件系统迭代很昂贵,甚至可能比func 中的处理更昂贵。在这种情况下,您可能会观察到 func 被顺序调用,当每个调用都在迭代器增量之前完成时。

标准库实现是permitted 忽略执行策略参数并串行执行算法。例如,如果无法对输入序列进行分区,则实现可能根本不会对函数调用进行并行化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-12
    相关资源
    最近更新 更多