Skip to content

Commit 4fba6bf

Browse files
isaevilaleksei-fedotovakukanovkboyarinov
authored
[oneTBB] Add a function to create a set of NUMA bound task arenas (#650)
Signed-off-by: Isaev, Ilya <[email protected]> Co-authored-by: Aleksei Fedotov <[email protected]> Co-authored-by: Alexey Kukanov <[email protected]> Co-authored-by: Konstantin Boyarinov <[email protected]>
1 parent 7f37f97 commit 4fba6bf

File tree

1 file changed

+48
-26
lines changed

1 file changed

+48
-26
lines changed

source/elements/oneTBB/source/task_scheduler/task_arena/task_arena_cls.rst

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,18 @@ A class that represents an explicit, user-managed task scheduler arena.
4242
int max_threads_per_core = task_arena::automatic;
4343
};
4444
45-
task_arena(int max_concurrency = automatic, unsigned reserved_for_masters = 1,
46-
priority a_priority = priority::normal);
47-
task_arena(constraints a_constraints, unsigned reserved_for_masters = 1,
48-
priority a_priority = priority::normal);
45+
task_arena(int max_concurrency = automatic, unsigned reserved_slots = 1,
46+
priority a_priority = priority::normal);
47+
task_arena(constraints constraints_, unsigned reserved_slots = 1,
48+
priority a_priority = priority::normal);
4949
task_arena(const task_arena &s);
5050
explicit task_arena(oneapi::tbb::attach);
5151
~task_arena();
5252
5353
void initialize();
54-
void initialize(int max_concurrency, unsigned reserved_for_masters = 1,
54+
void initialize(int max_concurrency, unsigned reserved_slots = 1,
5555
priority a_priority = priority::normal);
56-
void initialize(constraints a_constraints, unsigned reserved_for_masters = 1,
56+
void initialize(constraints constraints_, unsigned reserved_slots = 1,
5757
priority a_priority = priority::normal);
5858
void initialize(oneapi::tbb::attach);
5959
@@ -71,6 +71,9 @@ A class that represents an explicit, user-managed task scheduler arena.
7171
task_group_status task_arena::wait_for(task_group& tg);
7272
};
7373
74+
std::vector<task_arena> create_numa_task_arenas(task_arena::constraints constraints_ = {},
75+
unsigned reserved_slots = 0);
76+
7477
} // namespace tbb
7578
} // namespace oneapi
7679
@@ -182,28 +185,28 @@ Member types and constants
182185
Member functions
183186
----------------
184187

185-
.. cpp:function:: task_arena(int max_concurrency = automatic, unsigned reserved_for_masters = 1, priority a_priority = priority::normal)
188+
.. cpp:function:: task_arena(int max_concurrency = automatic, unsigned reserved_slots = 1, priority a_priority = priority::normal)
186189

187190
Creates a ``task_arena`` with a certain concurrency limit (``max_concurrency``) and priority
188191
(``a_priority``). Some portion of the limit can be reserved for application threads with
189-
``reserved_for_masters``. The amount for reservation cannot exceed the limit.
192+
``reserved_slots``. The amount for reservation cannot exceed the limit.
190193

191194
.. caution::
192195

193-
If ``max_concurrency`` and ``reserved_for_masters`` are
196+
If ``max_concurrency`` and ``reserved_slots`` are
194197
explicitly set to be equal and greater than 1, oneTBB worker threads will never
195198
join the arena. As a result, the execution guarantee for enqueued tasks is not valid
196199
in such arena. Do not use ``task_arena::enqueue()`` with an arena set to have no worker threads.
197200

198-
.. cpp:function:: task_arena(constraints a_constraints, unsigned reserved_for_masters = 1, priority a_priority = priority::normal)
201+
.. cpp:function:: task_arena(constraints constraints_, unsigned reserved_slots = 1, priority a_priority = priority::normal)
199202

200-
Creates a ``task_arena`` with a certain constraints(``a_constraints``) and priority
203+
Creates a ``task_arena`` with a certain constraints(``constraints_``) and priority
201204
(``a_priority``). Some portion of the limit can be reserved for application threads with
202-
``reserved_for_masters``. The amount for reservation cannot exceed the concurrency limit specified in ``constraints``.
205+
``reserved_slots``. The amount for reservation cannot exceed the concurrency limit specified in ``constraints``.
203206

204207
.. caution::
205208

206-
If ``constraints::max_concurrency`` and ``reserved_for_masters`` are
209+
If ``constraints::max_concurrency`` and ``reserved_slots`` are
207210
explicitly set to be equal and greater than 1, oneTBB worker threads will never
208211
join the arena. As a result, the execution guarantee for enqueued tasks is not valid
209212
in such arena. Do not use ``task_arena::enqueue()`` with an arena set to have no worker threads.
@@ -239,11 +242,11 @@ Member functions
239242

240243
After the call to ``initialize``, the arena parameters are fixed and cannot be changed.
241244

242-
.. cpp:function:: void initialize(int max_concurrency, unsigned reserved_for_masters = 1, priority a_priority = priority::normal)
245+
.. cpp:function:: void initialize(int max_concurrency, unsigned reserved_slots = 1, priority a_priority = priority::normal)
243246

244247
Same as above, but overrides previous arena parameters.
245248

246-
.. cpp:function:: void initialize(constraints a_constraints, unsigned reserved_for_masters = 1, priority a_priority = priority::normal)
249+
.. cpp:function:: void initialize(constraints constraints_, unsigned reserved_slots = 1, priority a_priority = priority::normal)
247250

248251
Same as above.
249252

@@ -329,6 +332,26 @@ Member functions
329332

330333
The behavior of this function is equivalent to ``this->execute([&tg]{ return tg.wait(); })``.
331334

335+
Non-member Functions
336+
--------------------
337+
338+
.. cpp:function:: std::vector<task_arena> create_numa_task_arenas(task_arena::constraints constraints_ = {}, unsigned reserved_slots = 0)
339+
340+
Returns a ``std::vector`` of non-initialized ``task_arena`` objects, each bound to a separate NUMA node.
341+
The number of created ``task_arena`` instances is equal to the number of NUMA nodes on the system,
342+
as determined by ``tbb::info::numa_nodes()``.
343+
344+
If an error occurs during system information discovery,
345+
returns a ``std::vector`` containing a single ``task_arena`` object created as
346+
``task_arena(constraints_.set_numa_id(task_arena::automatic), reserved_slots)``.
347+
348+
The ``constraints_`` argument can be specified to apply additional limitations to threads in
349+
the ``task_arena`` objects. For each created arena, the ``numa_id`` value in ``constraints_``
350+
is automatically set to the corresponding NUMA node ID from ``tbb::info::numa_nodes()``.
351+
352+
The ``reserved_slots`` argument allows reserving a specified number of slots in
353+
each ``task_arena`` object for application threads. By default, no slots are reserved.
354+
332355
Example
333356
-------
334357

@@ -343,22 +366,21 @@ to the corresponding NUMA node.
343366
#include <vector>
344367
345368
int main() {
346-
std::vector<oneapi::tbb::numa_node_id> numa_nodes = oneapi::tbb::info::numa_nodes();
347-
std::vector<oneapi::tbb::task_arena> arenas(numa_nodes.size());
348-
std::vector<oneapi::tbb::task_group> task_groups(numa_nodes.size());
349-
350-
for (int i = 0; i < numa_nodes.size(); i++) {
351-
arenas[i].initialize(oneapi::tbb::task_arena::constraints(numa_nodes[i]));
352-
}
369+
std::vector<oneapi::tbb::task_arena> arenas = oneapi::tbb::create_numa_task_arenas();
370+
std::vector<oneapi::tbb::task_group> task_groups(arenas.size()-1);
353371
354-
for (int i = 0; i < numa_nodes.size(); i++) {
372+
for (int i = 1; i < arenas.size(); i++) {
355373
arenas[i].enqueue([]{
356374
/* executed by a thread pinned to the specified NUMA node */
357-
}, task_groups[i]);
375+
}, task_groups[i-1]);
358376
}
359377
360-
for (int i = 0; i < numa_nodes.size(); i++) {
361-
arenas[i].wait_for(task_groups[i]);
378+
arenas[0].execute([] {
379+
/* executed by the main thread pinned to the NUMA node for arenas[0] */
380+
});
381+
382+
for (int i = 1; i < arenas.size(); i++) {
383+
arenas[i].wait_for(task_groups[i-1]);
362384
}
363385
364386
return 0;

0 commit comments

Comments
 (0)