Quite simply, a task just represents some amount of computation to be done. Each thread does something like this:
task* t = get_task();
Now this is a gross over-simplification, but at TBB's core this is what happens. A task is just a small piece of work to be completed, and that work is completed via the virtual call to execute(). Threads on the other hand have their own stack, and program counter. Tasks are just used to work with the TBB scheduler as you observed. But tasks can be balanced across multiple worker threads via the scheduler. Thus working with tasks gives you load-balancing almost for free. Unfortunately, unlike threads, TBB tasks cannot block... if they do, the entire worker thread will block.
Hope this helps.
You mean, the Task is just like a function, waiting to be called by the scheduler?
But,how does the working thread dynamicly invoke the Task to execute?
How does the scheduler decide how many worker thread to init?
Tasks are light-weight threads (concept is exactly the same). Tasks are disallowed to block (instead they provide continuations), in return you getting some lighter-weight scheduling. TBB tasks are targeted at computations, threads are general-purpose.
Think of a task as a light-weight thread. They both are "IExecutable".
Worker thread executes "virtual void execute()" method of a task.
By default TBB scheduler creates NUMBER_OF_LOGICAL_PROCESSORS number of threads. You may override this and specify exact number of worker threads.
Another question, what do you do tomake the Task morelightweigted thanthread?
What's you key point?
I noticed your implementation used pthread for Linux edition, but some of your code hard to understand.
Like what is Aarea used for?
There is a bunch of reasons.
Tasks are scheduled completely in user space, while threads are scheduled in kernel space.
Task scheduler is unfair (locality and performance are preferred), thread scheduler is fair.
Tasks run to completion, so space for stack is required (they are executed on worker thread's stack), threads require stack, so more memory pressure, so worse locality.
Creation and destruction of tasks is light-weight (it's just C++ objects), creation and destruction of threads is heavy-weight, requires additional bookkeeping in kernel.
Make no mistake: Tasks are executed by Threads. The gain comes from a variety of reasons, as Dmitriy suggests, but at the core is that TBB employs a thread pool so it pays the cost of thread creation once and then reuses those threads to handle the Tasks that are scheduled. Not having to create and destroy a thread for each Task is a big part of why it's more efficient, but not the only reason. The unfair scheduler Dmitriy mentioned can also be a win when it schedules related Tasks that can take advantage of data already cached in the HW thread by previous tasks.
TBB is a higher level library than the low level thread support libraries such as pthreads and Win32 and COM threads upon which it depends. Writing efficient and correct threaded code is complex, which is why there are so few of us that can do it so far. TBB is an attempt to hide some of the complexity of threading inside a stable, correct, reliable and efficient library. If you look under the hood, you're going to see some of that complexity ;-)
For details on the Arena, you might look to my response in this Scheduler Internals thread.