我最近对英特尔线程构建模块感兴趣。我想利用tbb::task_group
类来管理线程池。
我的第一个尝试是建立一个在另一个向量中复制向量的测试:我创建第n个任务,每个任务都要复制向量的连续切片。
但是,性能会随着线程数的增加而降低。我在另一个线程池实现中也得到了相同的结果。使用TBB 2018 Update 5,在8 i7核心盒上的debian strecth上使用gcc 6.3,我得到以下图来复制1'000'000元素的向量:
第n个真实用户
1 0.808s 0.807s
2 1.068s 2.105s
4 1.109s 4.282s
也许有人会帮助我理解这个问题。这是代码:
#include<iostream>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include "tbb/task_group.h"
#include "tbb/task_scheduler_init.h"
namespace mgis{
using real = double;
using size_type = size_t;
}
void my_copy(std::vector<mgis::real>& d,
const std::vector<mgis::real>& s,
const mgis::size_type b,
const mgis::size_type e){
const auto pb = s.begin()+b;
const auto pe = s.begin()+e;
const auto po = d.begin()+b;
std::copy(pb,pe,po);
}
int main(const int argc, const char* const* argv) {
using namespace mgis;
if (argc != 3) {
std::cerr << "invalid number of arguments\n";
std::exit(-1);
}
const auto ng = std::stoi(argv[1]);
const auto nth = std::stoi(argv[2]);
tbb::task_scheduler_init init(nth);
tbb::task_group g;
std::vector<real> v(ng,0);
std::vector<real> v2(ng);
for(auto i =0; i!=2000;++i){
const auto d = ng / nth;
const auto r = ng % nth;
size_type b = 0;
for (size_type i = 0; i != r; ++i) {
g.run([&v2, &v, b, d] { my_copy(v2, v, b, b + d + 1); });
b += d+1;
}
for (size_type i = r; i != nth; ++i) {
g.run([&v2, &v, b, d] { my_copy(v2, v, b, b + d); });
b += d ;
}
g.wait();
}
return EXIT_SUCCESS;
}
答案 0 :(得分:4)
tbb::parallel_for
而不是手动拆分范围,而无需使用task_group
。此外,一一调用任务具有线性复杂度,parallel_for
具有对数复杂度。