アノテーションをインテル® oneAPI スレッディング・ビルディング・ブロック (oneTBB) コードに置き換える

ここでは、インテル® oneAPI スレッディング・ビルディング・ブロック (oneTBB) の並列フレームワーク・コードを追加して、インテル® Advisor アノテーションで推奨された並列処理を実装する手順を説明します。

アノテーションを oneTBB コードに置き換える際に推奨される手順は以下のとおりです。

  1. LOCK アノテーションをガイドとして、共有リソースの適切な同期を追加します。
  2. 並列タスクを使用して非決定論的な動作を追加する前に、問題がないか検証するためテストを行います。
  3. サイト/タスクのアノテーションをガイドとして、oneTBB のタスクやループを生成するコードを追加します。
  4. プログラムが正しく動作することを確認するため、単一のスレッドでテストを行います。
  5. マルチスレッドが期待どおりに動作することを確認するため、複数のスレッドでテストを行います。

oneTBB 並列フレームワークは、ワーカースレッドを自動的に生成します。一般に、開発者はタスクについてのみ考え、ワーカースレッドの生成と破棄はフレームワークに任せるべきです。

ワーカースレッドの生成と破棄で何らかの制御が必要である場合、oneTBB リファレンス・マニュアルの task_scheduler_init を参照してください。

次の表は、並列処理が適用可能な典型的な例を示します。左のカラムはアノテーションが追加されたシリアルコードで、右カラムは等価な oneTBB 並列コードです。

インテル® Advisor のアノテーションを追加したシリアルコード oneTBB を使用した並列コード
// ロック 
ANNOTATE_LOCK_ACQUIRE(); 
     Body(); 
ANNOTATE_LOCK_RELEASE():
// oneTBB で提供される各種ミューテックス・タイプを使用してロック例えば、次のようになります: 
#include <tbb/tbb.h>
 ...
 tbb::mutex g_Mutex;
 ...
{ 
     tbb::mutex::scoped_lock lock(g_Mutex); 
     Body(); 
}
// 1 タスクの Do-All カウント付きループ 
ANNOTATE_SITE_BEGIN(site); 
     for (i = 0; i < N; ++) { 
          ANNOTATE_ITERATION_TASK(task); 
               {statement;} 
     } 
ANNOTATE_SITE_END();
// ラムダ式を使用した Do-All カウントループ
#include <tbb/tbb.h>
  ...
  tbb::parallel_for(0,N,[&](int I) { 
    statement;
  });

// 複数のタスクを生成 
ANNOTATE_SITE_BEGIN(site); 
     ANNOTATE_TASK_BEGIN(task1); 
          statement-or-task1; 
     ANNOTATE_TASK_END(); 
     ANNOTATE_TASK_BEGIN(task2); 
          statement-or-task2; 
     ANNOTATE_TASK_END(); 
ANNOTATE_SITE_END();
// ラムダ式を使用した複数タスクの生成
#include <tbb/tbb.h>

  ...
  tbb::parallel_invoke(
    [&]{statement-or-task1;},
    [&]{statement-or-task2;}
  );

一般的な並列プログラミング・パターンに関する情報と、それらを oneTBB を使用して実装する方法については、oneTBB ヘルプの「デザインパターン」をご覧ください。