TBB 并行化解析与引导::精神::qi

TBB parallelization of parsing with boots::spirit::qi

本文关键字:精神 qi 并行化 TBB      更新时间:2023-10-16

在我的程序中,我使用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,这将为这些独立任务的链启用管道类型的并行性。