tbb::task_scheduler_init から移行#
tbb::task_scheduler_init は、以前のバージョンのスレッディング・ビルディング・ブロック (TBB) では多目的機能を持っていました。このセクションでは、さまざまなユースケースと、それらを oneTBB でどのようにカバーできるか説明します。
スレッド数の管理#
デフォルトのスレッド数を照会#
oneapi::tbb::info::default_concurrency() は、暗黙的または明示的な
task_arenaのデフォルトで作成される最大並行実行数を返します。oneapi::tbb::this_task_arena::max_concurrency() は、現在のコンテキスト内で並列アルゴリズムが使用できる最大スレッド数を返します(暗黙的なアリーナが初期化されていない場合はデフォルト)。
oneapi::tbb::global_control::active_value(tbb::global_control::max_allowed_parallelism) は、スレッドプールの現在の制限数を返します(oneTBB スケジューラーが初期化されていない場合はデフォルト)。
最大並行実行数の設定#
task_arena(/* max_concurrency */) は、
task_arena内で実行される並列アルゴリズムの最大並行実行数を制限します。tbb::global_control(tbb::global_control::max_allowed_parallelism, /* max_concurrency */) は、oneTBBワーカースレッドの総数を制限します。
例#
デフォルトの並列処理。
#include <oneapi/tbb/info.h>
#include <oneapi/tbb/parallel_for.h>
#include <oneapi/tbb/task_arena.h>
#include <cassert>
int main() {
// デフォルトのスレッド数を取得
int num_threads = oneapi::tbb::info::default_concurrency();
// デフォルトの並列処理を実行
oneapi::tbb::parallel_for(/* ...*/ [] {
// スレッドの最大数をアサート
assert(num_threads == oneapi::tbb::this_task_arena::max_concurrency());
});
// デフォルトの task_arena を作成
oneapi::tbb::task_arena arena;
arena.execute([]{
oneapi::tbb::parallel_for( /* ... */ [] {
// スレッドの最大数をアサート
assert(num_threads == oneapi::tbb::this_task_arena::max_concurrency());
});
});
return 0;
}制限された並列処理。
#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() {
// 4 つのスレッドを持つカスタム task_arena を作成
oneapi::tbb::task_arena arena(4);
arena.execute([]{
oneapi::tbb::parallel_for( /* ... */ [] {
// このアリーナはスレッドに制限されています
assert(oneapi::tbb::this_task_arena::max_concurrency() == 4);
});
});
// すべての oneTBB 並列インターフェースのスレッド数を 2 に制限します
oneapi::tbb::global_control global_limit(oneapi::tbb::global_control::max_allowed_parallelism, 2);
// デフォルトの並列処理
oneapi::tbb::parallel_for( /* ... */ [] {
// スレッドは 2 つまでしか期待できませんが、tbb::this_task_arena::max_concurrency() はより大きな値を返す可能性があります
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( /* ... */ [] {
// スレッドは 2 つまでしか期待できませんが、tbb::this_task_arena::max_concurrency() は 4 です
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;
}スレッド・スタック・サイズの設定#
oneapi::tbb::global_control(oneapi::tbb::global_control::thread_stack_size, /* stack_size */) を使用して、oneTBB ワーカースレッドのスタックサイズを設定します。
#include <oneapi/tbb/parallel_for.h>
#include <oneapi/tbb/global_control.h>
int main() {
// oneTBB ワーカー スレッドのスタックサイズを 16 MB に設定します。
// メインスレッドのスタックサイズは、システムのドキュメントに従って、
// 例えばアプリケーションの起動時に設定する必要があることに注意してください。
oneapi::tbb::global_control global_limit(tbb::global_control::thread_stack_size, 16 * 1024 * 1024);
oneapi::tbb::parallel_for( /* ... */ [] {
// スタックに大きな配列を作成
char big_array[10*1024*1024];
});
return 0;
}oneTBB スケジューラーを終了#
task_scheduler_handle を使用すると、oneTBB ワーカースレッドの完了を待機できます。
#include <oneapi/tbb/global_control.h>
#include <oneapi/tbb/parallel_for.h>
int main() {
oneapi::tbb::task_scheduler_handle handle{tbb::attach{}};
// ここで並行ワークを行う
oneapi::tbb::parallel_for(/* ...*/);
oneapi::tbb::finalize(handle);
return 0;
}