Boost:创建对象并使用线程填充向量
Posted
技术标签:
【中文标题】Boost:创建对象并使用线程填充向量【英文标题】:Boost: Creating objects and populating a vector with threads 【发布时间】:2017-11-05 00:48:16 【问题描述】:使用基于this boost asio 的线程池,在这种情况下,该类被命名为ThreadPool
,我想并行化std::vector<boost::shared_ptr<T>>
类型的向量的填充,其中T
是一个struct
,其中包含一个std::vector<int>
类型的向量,其内容和大小在结构初始化后动态确定。
不幸的是,我在 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;
在进行了一些挖掘之后,我认为性能不佳可能是由于线程争夺内存访问,但我的新手状态让我无法利用这种洞察力。 您能否使用多个线程(最好是在线程池中)有效地填充指针向量?
【问题讨论】:
【参考方案1】:您没有提供足够的详细信息或Minimal, Complete, and Verifiable example,所以请期待大量猜测。
createT
是一个“便宜”的功能。调度任务及其执行的开销要昂贵得多。这就是为什么你的表现不好。要从并行性中获得提升,您需要具有适当的工作粒度和工作量。粒度意味着每个任务(在您的情况下是一次调用createT
)应该足够大以支付多线程开销。最简单的方法是将createT
呼叫分组以获得更大的任务。
【讨论】:
我同意gruffalo,而且因为你只是模拟工作,你可以只使用睡眠。但我确实想提出几点。new T()
没有做你认为的事情。它实际上不是分配一个默认构造的 T,而是创建一个临时的默认构造 T,然后为新分配的对象使用 复制构造函数,最后销毁临时对象。此外,为所有变量声明包含类型更清楚,尤其是当它们在自己的行中时。
感谢您的帮助。事实证明,多线程正在改善程序的运行时间,但 ctime 没有透露这一点,因为它测量的是 CPU 时间而不是挂钟时间。切换到 chrono 使加速变得明显。无论如何,批处理作业是一个很好的建议,并且确实进一步提高了程序的运行时性能。所以我会将此标记为正确答案。以上是关于Boost:创建对象并使用线程填充向量的主要内容,如果未能解决你的问题,请参考以下文章