Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

use tbb::task in event driven application

dophine
Beginner
696 Views

I don't know if it is suitable or preferred to use tbb::task instead of boost::thread in event driven application. Is there anyone encounter before?

sample code:

class ProcessA 
{
public:
    void operator()()
    {
        //do something
    }
};

class ProcessB
{
public:
    void operator()()
    {
        //do something
    }
};

int main(int argc, char** argv)
{    
    task_group group;

    // recv a message
    if (type = MsgA)
    {
      group.run(ProcessA());
    }
    else
    {
      group.run(ProcessB());
    }

    group.wait();
0 Kudos
1 Solution
Michael_V_Intel
Employee
696 Views

The main difference between threads and TBB tasks, is that TBB tasks are scheduled to be executed by one of the threads in the TBB thread pool. If you were to receive many messages and create a boost thread to execute each one, you could potentially have many threads fighting for resources on the cores. If instead, you create a TBB task to process each message, these lightweight tasks would be scheduled on to the TBB worker threads. By default, TBB creates one worker thread per core (or thread context when using Hyperthreading). So you would avoid oversubscription, and since its faster to create a task than a thread, the overhead per message should be lower.

That being said though… if you depend on messages being processed concurrently with the main thread or with each other, then only a thread guarantees that. In TBB, the parallelism is not guaranteed. For example, in your code above it would be possible that the main thread that calls "run" will also be asked to execute the task inside of the call to "group.wait()". Or, it is also possible that a worker thread may execute processA and the main thread will just wait at the “group.wait()”. It all depends on what the TBB scheduler decides to do. So there is no guaranteed parallelism. Often, when the TBB scheduler does not use parallelism it is because using the parallelism would actually result in a slower execution. But if your application requires parallelism for correctness, not just performance, then only threads will suffice.

View solution in original post

0 Kudos
3 Replies
Michael_V_Intel
Employee
697 Views

The main difference between threads and TBB tasks, is that TBB tasks are scheduled to be executed by one of the threads in the TBB thread pool. If you were to receive many messages and create a boost thread to execute each one, you could potentially have many threads fighting for resources on the cores. If instead, you create a TBB task to process each message, these lightweight tasks would be scheduled on to the TBB worker threads. By default, TBB creates one worker thread per core (or thread context when using Hyperthreading). So you would avoid oversubscription, and since its faster to create a task than a thread, the overhead per message should be lower.

That being said though… if you depend on messages being processed concurrently with the main thread or with each other, then only a thread guarantees that. In TBB, the parallelism is not guaranteed. For example, in your code above it would be possible that the main thread that calls "run" will also be asked to execute the task inside of the call to "group.wait()". Or, it is also possible that a worker thread may execute processA and the main thread will just wait at the “group.wait()”. It all depends on what the TBB scheduler decides to do. So there is no guaranteed parallelism. Often, when the TBB scheduler does not use parallelism it is because using the parallelism would actually result in a slower execution. But if your application requires parallelism for correctness, not just performance, then only threads will suffice.

0 Kudos
dophine
Beginner
696 Views
Thank you. I will stick with thread.
0 Kudos
jimdempseyatthecove
Honored Contributor III
696 Views
There are often nuances with an application that are not expressed in sketch code, such as presented in your first post. In particular:

I assume you have something like this

    do
        type = get message
        select process by message type
    end do

Unstated in your post is/are:

a) are (can) messages be received asychronous from processing?
b) are (can) messages be received faster than processing?, To what extent?
c) can a process for a given message type run concurrently with a different message of the same type?
d) if No to c) are messages of the same type to be enqueued for single file processing or should secondary, tertiary, ... message be discarded?
e) do we assume messages of different type are intended to run concurrently?

Those questions are for starters.

Jim Dempsey
0 Kudos
Reply