所以我遇到了英特尔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里面还有更多内容)
答案 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可以通过并行处理来帮助组织可扩展计算并减少每个请求的延迟。