Explicit, user-managed task scheduler arena representation.
class task_arena;
#define TBB_PREVIEW_TASK_ARENA 1 #include “tbb/task_arena.h”
A task_arena class represents an internal task scheduler object where a number of threads, limited by a maximal concurrency level, share and execute tasks.
The concurrency level of a task_arena is isolated and not affected by previous task_scheduler_init specifications.
A task_arena object keeps a reference to its internal representation, but does not fully control its lifetime. It cannot be destroyed until it contains tasks and/or other worker threads reference it.
Each user thread that explicitly or implicitly creates a task_scheduler_init object contains an implicit internal task arena object. The tasks spawned or enqueued in an arena cannot be executed in a different arena.
namespace tbb { class task_arena { public: static const int automatic = implementation-defined; static int current_slot(); task_arena(int max_concurrency = automatic, unsigned reserved_for_masters = 1); task_arena(const task_arena &s); ~task_arena(); void initialize(); void initialize(int max_concurrency, unsigned reserved_for_masters = 1); void terminate(); bool is_active(); template<typename F> void enqueue( const F& f ); template<typename F> void enqueue( const F& f, priority_t p ); template<typename F> void execute(F& f); template<typename F> void execute(const F& f); }; }
The following example runs two parallel_for loops concurrently; one that is scalable and one that is not. The non-scalable loop is limited to at most 2 threads so that the majority of the threads can be saved for the more scalable loop. It uses task_group to wait for a specific subset of tasks.
tbb::task_scheduler_init def_init; // Use the default number of threads tbb::task_arena limited(2);// no more than 2 threads in this arena tbb::task_group tg; limited.enqueue([&]{ // use at most 2 threads tg.run([]{ // run in task group tbb::parallel_for(1, N, unscalable_work()); }); }); // Run another job concurrently with the loop above // It can use the default number of threads: tbb::parallel_for(1, M, scalable_work()); // Put the wait for the task group inside execute() // This will wait only for the tasks that are in // this task group. arena.execute([&]{ tg.wait(); });
Member | Description |
---|---|
task_arena(int max_concurrency = automatic, unsigned reserved_for_masters = 1) |
Creates a task_arena with certain concurrency limit and some portion of it reserved for application threads. NoteFor the community preview implementation of task_arena, the only valid values for reserved_for_masters are 0 and 1. |
static const int automatic |
When passed as max_concurrency to the above constructor, arena concurrency will be automatically set based on the hardware configuration. |
task_arena(const task_arena&) |
Copies settings from another task_arena instance. |
~task_arena() |
Removes the reference to the internal arena representation, and destroys the task_arena() instance. Not thread safe w.r.t. concurrent invocations of other methods. |
void initialize();
void initialize(int max_concurrency, unsigned reserved_for_masters = 1); |
Performs actual initialization of internal
arena representation. If arguments are specified, overrides previous concurrency settings.
Has no effect when called on already initialized arena.
NoteAfter the call to initialize, the arena concurrency is fixed and cannot be changed. |
void terminate() | Removes the reference to the internal arena representation without destroying the task_arena object, which can then be re-used. Not thread safe w.r.t. concurrent invocations of other methods. |
bool is_active() | Returns true if the arena has been initialized, false otherwise. |
template<F> void enqueue(const F&) |
Enqueues a task into the arena to process specified functor and immediately returns. NoteDoes not require the calling thread to join the arena; i.e. any number of threads outside of the arena can submit work to the arena without blocking.CautionThere is no guarantee that tasks enqueued in an arena execute concurrently with respect to any other arena’s tasks. |
template<F> void enqueue(const F&, priority_t) |
Enqueues a task with specified task priority. Is similar to enqueue( const F& ) in all other ways. |
template<F> void
execute(F&)
template<F> void execute(const F&)
|
If possible, the calling thread joins the arena and executes the specified functor, then leaves the arena and returns to previous task scheduler state. If not possible to join, the call wraps the functor into a task, enqueues it in the arena and waits on an OS kernel synchronization object for task completion. NoteAny number of threads outside of the arena can submit work to the arena and be blocked. However, only the maximal number of threads specified for the arena can participate in executing tasks.NoteMay decrement the arena's demand for worker threads, causing a worker to leave, and thereby freeing a slot for the calling thread. |
static int current_slot() |
Returns: The index of the slot that the calling thread is assigned to in its current arena (if any). If the thread is not initialized with TBB, returns -1. This method can be used, for example, by a task_scheduler_observer to pin threads entering an arena to specific hardware. |