Migrating from tbb::task_scheduler_init#

tbb::task_scheduler_init was a multipurpose functionality in the previous versions of Threading Building Blocks (TBB). This section considers different use cases and how they can be covered with oneTBB.

Managing the number of threads#

Querying the default number of threads#

Setting the maximum concurrency#

Examples#

The default parallelism:

#include <oneapi/tbb/info.h>
#include <oneapi/tbb/parallel_for.h>
#include <oneapi/tbb/task_arena.h>
#include <cassert>

int main() {
    // Get the default number of threads
    int num_threads = oneapi::tbb::info::default_concurrency();

    // Run the default parallelism
    oneapi::tbb::parallel_for( /* ... */ [] {
        // Assert the maximum number of threads
        assert(num_threads == oneapi::tbb::this_task_arena::max_concurrency());
    });

    // Create the default task_arena
    oneapi::tbb::task_arena arena;
    arena.execute([]{
        oneapi::tbb::parallel_for( /* ... */ [] {
            // Assert the maximum number of threads
            assert(num_threads == oneapi::tbb::this_task_arena::max_concurrency());
        });
    });

    return 0;
}

The limited parallelism:

#include <oneapi/tbb/info.h>
#include <oneapi/tbb/parallel_for.h>
#include <oneapi/tbb/task_arena.h>
#include <oneapi/tbb/global_control.h>
#include <cassert>

int main() {
    // Create the custom task_arena with four threads
    oneapi::tbb::task_arena arena(4);
    arena.execute([]{
        oneapi::tbb::parallel_for( /* ... */ [] {
            // This arena is limited with for threads
            assert(oneapi::tbb::this_task_arena::max_concurrency() == 4);
        });
    });

    // Limit the number of threads to two for all oneTBB parallel interfaces
    oneapi::tbb::global_control global_limit(oneapi::tbb::global_control::max_allowed_parallelism, 2);

    // the default parallelism
    oneapi::tbb::parallel_for( /* ... */ [] {
        // No more than two threads is expected; however, tbb::this_task_arena::max_concurrency() can return a bigger value
        int thread_limit = oneapi::tbb::global_control::active_value(oneapi::tbb::global_control::max_allowed_parallelism);
        assert(thread_limit == 2);
    });

    arena.execute([]{
        oneapi::tbb::parallel_for( /* ... */ [] {
            // No more than two threads is expected; however, tbb::this_task_arena::max_concurrency() is four
            int thread_limit = oneapi::tbb::global_control::active_value(oneapi::tbb::global_control::max_allowed_parallelism);
            assert(thread_limit == 2);
            assert(tbb::this_task_arena::max_concurrency() == 4);
        });
    });

    return 0;
}

Setting thread stack size#

Use oneapi::tbb::global_control(oneapi::tbb::global_control::thread_stack_size, /* stack_size */) to set the stack size for oneTBB worker threads:

#include <oneapi/tbb/parallel_for.h>
#include <oneapi/tbb/global_control.h>

int main() {
    // Set 16 MB of the stack size for oneTBB worker threads.
    // Note that the stack size of the main thread should be configured in accordace with the
    // system documentation, e.g. at application startup moment
    oneapi::tbb::global_control global_limit(tbb::global_control::thread_stack_size, 16 * 1024 * 1024);

    oneapi::tbb::parallel_for( /* ... */ [] {
        // Create a big array in the stack
        char big_array[10*1024*1024];
    });

    return 0;
}

Terminating oneTBB scheduler#

task_scheduler_handle_reference allows waiting for oneTBB worker threads completion:

#include <oneapi/tbb/global_control.h>
#include <oneapi/tbb/parallel_for.h>

int main() {
    oneapi::tbb::task_scheduler_handle handle{tbb::attach{}};
    // Do some parallel work here
    oneapi::tbb::parallel_for(/* ... */);
    oneapi::tbb::finalize(handle);
    return 0;
}