提升:创建对象并用线程填充矢量

Boost: Creating objects and populating a vector with threads

本文关键字:填充 线程 创建对象 提升      更新时间:2023-10-16

使用这个基于 boost asio 的线程池,在这种情况下,类被命名为 ThreadPool ,我想并行化 std::vector<boost::shared_ptr<T>> 型向量的总体,其中 T 是一个包含 std::vector<int> 型向量struct,其内容和大小在结构初始化后动态确定。

不幸的是,我是 c++ 和多线程的新手,所以我解决这个问题的尝试失败了。下面是一个过于简化的示例程序,用于对任务的非线程和线程版本进行计时。线程版本的性能非常可怕...

#include "thread_pool.hpp"
#include <ctime>
#include <iostream>
#include <vector>

using namespace boost;
using namespace std;

struct T {
  vector<int> nums = {};
};

typedef boost::shared_ptr<T> Tptr;
typedef vector<Tptr> TptrVector;

void create_T(const int i, TptrVector& v) {
  v[i] = Tptr(new T());
  T& t = *v[i].get();
  for (int i = 0; i < 100; i++) {
    t.nums.push_back(i);
  }
}

int main(int argc, char* argv[]) {
  clock_t begin, end;
  double elapsed;
  // define and parse program options
  if (argc != 3) {
    cout << argv[0] << " <num iterations> <num threads>" << endl;
    return 1;
  }
  int iterations = stoi(argv[1]),
      threads    = stoi(argv[2]);
  // create thread pool
  ThreadPool tp(threads);
  // non-threaded
  cout << "non-thread" << endl;
  begin = clock();
  TptrVector v(iterations);
  for (int i = 0; i < iterations; i++) {
    create_T(i, v);
  }
  end = clock();
  elapsed = double(end - begin) / CLOCKS_PER_SEC;
  cout << elapsed << " seconds" << endl;
  // threaded
  cout << "threaded" << endl;
  begin = clock();
  TptrVector v2(iterations);
  for (int i = 0; i < iterations; i++) {
    tp.submit(boost::bind(create_T, i, v2));
  }
  tp.stop();
  end = clock();
  elapsed = double(end - begin) / CLOCKS_PER_SEC;
  cout << elapsed << " seconds" << endl;
  return 0;
}

经过一些挖掘,我认为性能不佳可能是由于线程争夺内存访问,但我的新手身份阻止我利用这种洞察力。您能否使用多个线程有效地填充指针向量,最好是在线程池中?

您既没有提供足够的详细信息,也没有提供最小、完整和可验证的示例,因此预计会有很多猜测。

createT是一个"便宜"的功能。计划任务及其执行开销要昂贵得多。这就是为什么你的表现很糟糕。为了从并行性中获得提升,您需要具有适当的工作粒度和工作量。粒度意味着每个任务(在您的情况下是一次调用createT)应该足够大,以支付多线程开销。最简单的方法是对createT呼叫进行分组以获得更大的任务。