微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我的并行 std::for_each 只使用 1 个线程?

如何解决为什么我的并行 std::for_each 只使用 1 个线程?

我正在尝试并行化此 C++ 代码(计算点的连续傅立叶变换,建模为 Dirac 脉冲),并且此代码编译并正常工作,但它仅使用 1 个线程。我还需要做些什么才能使多个线程工作?这是在具有 4 个内核(8 个线程)的 Mac 上使用 GCC 10 编译的。

vector<double> GetFourierImage(const Point pts[],const int num_samples,const int res,const double freq_step) {
  vector<double> fourier_img(res*res,0.0);
  double half_res = 0.5 * res;

  vector<int> rows(res);
  std::iota(rows.begin(),rows.end(),0);
  std::for_each(  // Why doesn't this parallelize?
      std::execution::par_unseq,rows.begin(),[&](int i) {
    double y = freq_step * (i - half_res);
    for (int j = 0; j < res; j++) {
      double x = freq_step * (j - half_res);

      double fx = 0.0,fy = 0.0;
      for (int pt_idx = 0; pt_idx < num_samples; pt_idx++) {
        double dot = (x * pts[pt_idx].x) + (y * pts[pt_idx].y);
        double exp = -2.0 * M_PI * dot;
        fx += cos(exp);
        fy += sin(exp);
      }
      fourier_img[i*res + j] = sqrt((fx*fx + fy*fy) / num_samples);
    }
  });

  return fourier_img;
}

解决方法

在 GCC 9 中,使用不同的执行策略时存在对 TBB 的硬依赖,如果不存在,则构建将失败。这在 GCC 10(并出现在 GCC 11 中)发生了变化,如果库不存在,则 for_each 将默认为顺序循环。这可以在 https://github.com/gcc-mirror/gcc/blob/releases/gcc-10.1.0/libstdc++-v3/include/bits/c++config#L679 处看到。要解决您的问题,请尝试使用 -ltbb 链接到 TBB。这解决了您在使用 GCC 11.2 的 Ubuntu 20.04 上遇到的相同问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。