英特尔tbb任务调度是否适合DBMS?

时间:2015-02-01 12:09:55

标签: c++ multithreading tbb

所以我遇到了英特尔TBB并问自己它适合某种DBMS吗?

因此,例如,我有一个称为进程查询的任务,它在我的系统中执行一个语句并通过返回参数返回一些内容。 这将是这样的例子:

class ProcessQuery : public task {
private:
    int a;
public:
    ProcessQuery(int n, char* result) :a(n){};
    task* execute() {
        //do something and write the result
    }
};

要执行此操作,我会举例如此(这只是一个例子!):

    tbb::task_scheduler_init init(tbb::task_scheduler_init::automatic);
//init of the parameter for the tasks
    ProcessQuery &q1 = *new(tbb::task::allocate_root()) ProcessQuery(1, r1);
    ProcessQuery &q2 = *new(tbb::task::allocate_root()) ProcessQuery(2, r2);
    ProcessQuery &q3 = *new(tbb::task::allocate_root()) ProcessQuery(3, r3);

    tbb::task::spawn(q1);
    tbb::task::spawn(q2);
    tbb::task::spawn(q3);

此外,我需要一些循环并检查是否有结果的任务,并将其发送回查询客户端。因此,将会有一个root任务,并将ProcessQuery任务作为子项。或者甚至任务将客户端作为参考传递,并在完成后发送结果。

这是合适的还是有一些更好的解决方案,或多或少开箱即用,具有很高的性能? (也许我对tbb的taskscheduler甚至错了,我知道的lib里面还有更多内容)

1 个答案:

答案 0 :(得分:1)

首先让我来修复你古老的例子。由于tbb::task是低级API,task_scheduler_init是可选的,因此我不建议从它们开始。请改用高级API,例如task_group

tbb::task_group tg;
int a;

tg.run([=a]{ /*do something and write the result*/ }); a++;
tg.run([=a]{ /*do something and write the result*/ }); a++;
tg.run([=a]{ /*do something and write the result*/ }); a++;
// ...
tg.wait(); // recommended before program termination

至于你的问题,TBB主要是为并行计算而设计的,它对阻止文件I / O和网络等操作没有足够的支持。因为这些操作会阻止操作系统中的工作线程并导致CPU资源利用不足,因为TBB限制了工作线程的数量以防止oversubscription

但是当阻塞操作仅限于一个线程并且TBB工作者处理它产生的事件时,TBB适用于异步I / O.当没有传入事件时主线程的过度使用存在一个小问题,但它可以在TBB调度程序中解决甚至修复。

这种生产者 - 消费者模式的简单高级方法是使用parallel_pipeline

void AsyncIO() {
    parallel_pipeline( /*max_number_of_live_token=*/ 
        4*task_scheduler_init::default_num_threads(),
        make_filter<void, event_t>(
            filter::serial,           // only one thread can get events
            [](flow_control& fc)-> event_t {
                event_t e;
                if( !get_event(e) ) {
                    fc.stop();        // finish pipeline
                    return event_t(); // empty event
                }
                return e;
            }
        ) &
        make_filter<event_t, void>(
            filter::parallel,         // events can be processed in parallel
            [&](event e) {
                process_event(e);
                enqueue_response(e);  // do not block when write/send back
            }
        )
    );
}

总而言之,如果您可以将操作拆分为阻塞和非阻塞,并将所有阻塞操作分离到专用线程,TBB可以通过并行处理来帮助组织可扩展计算并减少每个请求的延迟。