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

如何用运行时值实现无容器并行std::transform替代普通循环?

用并行std::transform替代索引循环的常规实现方法

需求说明

想要把以下普通索引循环:

std::vector<double> data(n, 0);
for(int i = 0; i < n; i++){
  data[i] = func(i);
}

替换为带并行执行策略的std::transform实现,期望的结构如下:

std::vector<double> data(n, 0);
std::transform(
      std::execution::par_unseq,
      /*from 0*/,
      /*to n*/,
      data.begin(),
      func);

目标是无需额外容器存储索引,且使用运行时值生成索引序列(而非constexpr值)。

当前解决方案

目前实现方式需要额外创建索引容器并填充,代码如下:

std::vector<size_t> indexes(n, 0);
auto indexFillFunc = [&indexes](const size_t &value){
    return &value - &indexes[0];
};

std::transform(
  std::execution::par_unseq,
  indexes.begin(),
  indexes.end(),
  indexes.begin(),
  indexFillFunc);

std::vector<double> data(n, 0);
std::transform(
  std::execution::par_unseq,
  indexes.begin(),
  indexes.end(),
  data.begin(),
  func);

但该方案需要额外维护索引容器,希望了解更常规的实现方式。

常规实现方法(C++20+)

利用C++20引入的std::views::iota视图,它支持运行时值生成连续整数序列,且无需分配额外内存。结合并行版std::transform即可实现需求:

标准std::transform写法

#include <vector>
#include <algorithm>
#include <execution>
#include <ranges>

std::vector<double> data(n, 0);
std::transform(
    std::execution::par_unseq,
    std::views::iota(0, static_cast<int>(n)).begin(),
    std::views::iota(0, static_cast<int>(n)).end(),
    data.begin(),
    func
);

C++20范围版写法(更简洁)

#include <vector>
#include <algorithm>
#include <execution>
#include <ranges>

std::vector<double> data(n);
std::ranges::transform(
    std::execution::par_unseq,
    std::views::iota(0, static_cast<int>(n)),
    data.begin(),
    func
);

注意事项

  • 需确保编译器支持C++20及以上标准,且标准库实现了std::views::iota和并行执行策略。
  • 编译时可能需要链接并行库:比如GCC需添加-fopenmp或链接libstdc++-parallel,MSVC需链接TBB库。

内容的提问来源于stack exchange,提问作者Gergely Tóth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 19:33:19