TBB 并行化解析与引导::精神::qi
TBB parallelization of parsing with boots::spirit::qi
在我的程序中,我使用Boost-Spirit-Qi来解析大型数据集。输入数据是连续记录。我正在尝试使用 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 个内核(单处理器)。我将不胜感激地指出我正确的算法并行化这项任务。
谢谢你的建议。
斯坦
您的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
,这将为这些独立任务的链启用管道类型的并行性。
相关文章:
- 提升精神:解析布尔表达式并简化为规范范式
- 如何克服提升精神AST混乱
- 增强精神解析器规则以检测语句中的特殊结尾
- 提升精神 V2 Qi 语法线程安全吗?
- 提升精神 QI:在元组上自动规则演绎,在替代函数中带有序列
- 提升::精神::qi::语法和可变参数模板
- 增强精神Qi-列表解析具有两个组件序列
- 为什么这个提升::精神::qi规则与输入不匹配
- TBB 并行化解析与引导::精神::qi
- 递归精神.Qi语法的分割错误
- 提升::精神::Qi 关键字和标识符
- 提升精神解析器 Lex->qi:让"undocumented" on_success机制发挥作用
- 提升::精神::QI规则减少解析错误
- 使用提升::精神::qi 重新合成中间值
- 逻辑非运算符在提升::精神::QI 中不起作用
- 更丰富的错误返回消息用于提升::精神::qi 解析
- 提升精神2:跟随QI的进度百分比::p阿尔瑟。我的代码中有什么不好?
- 重载精神语法以使用lexer或qi解析器
- 为什么这个提升::精神::qi规则没有成功解析?
- 提升精神:Lex + Qi错误报告