提升:创建对象并用线程填充矢量
Boost: Creating objects and populating a vector with threads
使用这个基于 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
呼叫进行分组以获得更大的任务。
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 在C++中使用cURL和多线程
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在cuda线程之间共享大量常量数据
- 如何将元素添加到数组的线程安全函数?
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- 如何在<N>不发生内存泄漏的情况下同时(线程安全)填充 c++11 std::map<std::string,std::bitset*>?
- 填充和保存线程之间的共享缓冲区
- C++使用多线程的无序列图填充
- 当结构数组在主线程中填充数据时,从结构数组的低索引元素读取是否线程安全
- 优化寄存器/L1中数据的每线程复制和0填充
- boost线程未填充通过引用传递的本地对象
- 尝试用函数填充线程向量 - 错误
- OpenMP线程之间的矢量填充
- 填充计数'buckets' CUDA 线程
- 在CUDA内核中填充一个数组或列表,但不是在每个线程中
- c++使用' .reserve() '填充' std::vector '作为防止多线程缓存无效和错误共享的一种方
- 在单独的线程上填充、填充QTreeView树
- C/ c++线程调用填充内存