You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

并行执行策略是否要求迭代器引用类型为左值?

C++并行算法对非左值范围无法并行的标准合规性问题

我排查到一个代码性能问题:对非左值范围调用带并行执行策略的算法时无法实现并行。以下是演示该行为的代码:

#include <chrono>
#include <iostream>
#include <thread>
#include <algorithm>
#include <execution>
#include <ranges>

#include <tbb/parallel_for.h>

struct Timer {
    Timer() : start{std::chrono::high_resolution_clock::now()} {}
    ~Timer() {
        auto stop = std::chrono::high_resolution_clock::now();
        std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(stop - start) << '\n';
    }
    std::chrono::time_point<std::chrono::high_resolution_clock> start;
};

auto fn    = [](int) {
    using namespace std::chrono_literals;
    std::this_thread::sleep_for(1ms);
};

void run(std::ranges::range auto&& rng) {
    Timer timer;
    std::for_each(std::execution::par, rng.begin(), rng.end(), fn);
}

int main() {
    constexpr int N = 200;
    run(std::views::iota(0, N));                                                                // 无法并行
    run(std::array<int, N>{});                                                                  // 可以并行
    run(std::array<int, N>{} | std::views::transform([](auto& elem) { return elem * 2; }));     // 无法并行
    run(std::array<int, N>{} | std::views::transform([](auto& elem) -> int& { return elem; })); // 可以并行
    {
        Timer timer;
        tbb::parallel_for(0, N, fn);                                                            // 可以并行
    }
    return 0;
}

假设并行函数仅需要const访问(这非常常见),第三种情况的限制是否符合C++标准要求?


这种限制是符合C++标准要求的。

核心原因在于C++标准对并行算法的迭代器和范围有明确约束:

  • 使用std::execution::par这类并行执行策略时,算法要求迭代器必须是随机访问迭代器,同时范围需要支持安全的分割与多线程访问。
  • 第三种情况中,transform视图返回的是临时int值,对应迭代器的引用类型是右值(而非左值引用)。每次解引用迭代器都会生成新的临时对象,并行算法无法保证多线程访问时的语义一致性与执行效率——标准并没有强制要求实现必须支持对这类非左值范围的并行处理,因此标准库会选择退化为串行执行。

哪怕并行函数只需要const访问也无法改变这个结果,因为问题的根源不是元素的可修改性,而是迭代器能否提供稳定的左值引用,让多个线程可以安全高效地访问元素。


内容的提问来源于stack exchange,提问作者MarkB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 11:57:13