在我的程序中,我使用Boost-Spirit来解析大型数据集。输入数据是顺序记录。我试图使用TBB来提高解析的效率。并行处理的程序如下:
typedef map<string, data_struct_t> mdata_t;
vector<string> text;
mdata_t data;
parallel_for(blocked_range<size_t>(0, input.size(), gs),
[&] (blocked_range<size_t>& r) {
data_struct_t cs;
mdata_t cr;
string s;
for(size_t i=r.begin(); i<r.end(); i++) {
s = text[i];
Parser::task1(s, cs);
Parser::task2(s, cs);
Parser::task3(s, cs);
....
Parser::task8(s, cs);
cr.insert(std::make_pair(cs.title, cs));
}
data.insert(cr.begin(), cr.end());
}, ap);我的程序只使用10%的CPU (2个CPU,16个核心),工作在8个核心。我不明白为什么不使用其余的8个核心(单处理器)。我很感激能告诉我正确的算法并行化这个任务。
谢谢你的建议。
Stan
发布于 2015-01-22 14:46:45
您的input.size()可能很小,或者gs太大,无法阻止创建足够多的并行性。否则,如果需要考虑线程数,那么在启动程序时检查程序的进程(关联)掩码,以及如何初始化TBB (例如,如果tbb::task_scheduler_init是用少量线程创建的)。
至于CPU利用率,预计当您的工作是IO绑定,即读取一个文件.完成一个并行迭代所需的时间也可能与另一个迭代有很大的不同。在这种情况下,可以在创建所有线程之前完成小的迭代。(当所有线程运行时,如果您想要精确地测量加速比,您应该手动等待)
建议:
您在data.insert中有一个错误,因为std::map对并发修改不安全。使用tbb::concurrent_unordered_map或仅使用tbb::parallel_reduce来合并从不同线程在cr中收集的部分结果。
如果任务没有共享全局状态,模式Parser::task1(s, cs); ... Parser::task8(s, cs);也可以并行化。请参阅tbb::parallel_pipeline,它将为这些独立任务的链启用流水线类型的并行性。
https://stackoverflow.com/questions/28089138
复制相似问题