【问题标题】:C++ process each element of a vector in parallel with threadsC++ 与线程并行处理向量的每个元素
【发布时间】:2021-05-20 13:51:32
【问题描述】:

我对现代 C++ 多线程有点陌生,我想知道哪种方法是并行处理向量的每个元素的正确方法。更具体地说,假设以下情况:

struct Neighbor
{
  int idx;
  float score;
};

struct Cluster
{
  std::vector<int> cameras;
  std::unordered_map<int, std::vector<Neighbor>> neighbors;
};

class Test
{
  std::vector<Cluster> clusters;
  void DoSomething();
  void DoSomethingForCluster(const int i);
};

我想并行处理 clusters 向量的每个元素(即填充地图),因为每个元素之间没有依赖关系。我的第一个猜测是尝试类似:

void Test::DoSomething()
{
  std::vector<std::thread> th_vec;

  for (int i = 0; i < clusters.size(); i++)
  {
    th_vec.push_back(std::thread(&Test::DoSomethingForCluster, this, i));
  }

  for (auto& t : th_vec)
  {
    t.join();
  }
}

void Test::DoSomethingForCluster(const int i)
{
  for (const auto& cam : clusters[i].cameras)
  {
    std::vector<Neighbor> n;
    // Do something to fill the vector n
    clusters[i].neighbors.insert(std::make_pair(cam, n));
  }
}

代码可以顺利构建和运行,但我想了解是否有更好或更有效的方法来完成此类任务。例如,为每个元素启动一个线程是否有意义?任何建议或帮助都非常感谢,在此先感谢您。

【问题讨论】:

  • 我会说这看起来很不错,但是对于“为每个元素启动一个线程是否有意义”我会说不(除非你的元素很少)。如果您启动的每个线程都大量使用 CPU 或其他共享资源,那么您需要额外考虑。对于 CPU 密集型线程,我建议不要启动比硬件支持更多的线程 - 或类似情况。
  • @TedLyngmo 假设我的 CPU 中有 100 个元素和 4 个内核。运行 4 个线程(每个处理 25 个元素)是否比运行 100 个线程(每个处理 1 个元素)更有意义?
  • 是的,但您可能拥有超线程内核,因此每个内核可能运行 2 个线程。您可以通过调用std::thread::hardware_concurrency() 来检查运行时的限制。我认为它会为您的 4 核 CPU 报告 8 个。更多线程可能只会减慢速度。

标签: c++ multithreading c++11 parallel-processing


【解决方案1】:

我自己并没有这样做,但我认为你会这样做的方式是使用 for_each 和执行策略:

std::for_each(std::execution::parallel_policy, clusters.begin(), clusters.end() []() {....} );

让库决定创建多少线程。

您可以在 Google 上搜索“C++ 执行策略”以获取更多信息。

【讨论】:

  • 我用过这个(应该是std::execution::par btw),它很棒——但不幸的是,这个问题被标记为 C++11。在 C++17 中添加了并行执行策略。
猜你喜欢
  • 1970-01-01
  • 2012-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-03
相关资源
最近更新 更多