オープンソース化された並列化テンプレートクラスライブラリ「Intel Threading Building Blocks」入門 2ページ

TBBを利用するメリット

 さて、並列処理を実装する方法として、TBBのほかにも前述のようにマルチスレッドやOpenMPといった方法がある。これらと比較してTBBのメリットはどこにあるのだろうか。

 まずマルチスレッドによる実装との比較であるが、TBBでは「複数のスレッドを作成し、適切なデータに対して適切な処理を割り当てる」という処理が、テンプレート関数という形であらかじめ用意されている。そのため、データとロジックのみを用意するだけで、面倒なスレッドの生成やデータの分割といった部分を気にせずに並列処理を実装できる。

 一方OpenMPでは、for/whileループの並列処理やブロックごとの並列処理といった、スレッドの生成に関わる部分については面倒を見なくてもよいものの、データの分割については基本的には自前で処理しなければならない。また、OpenMPは並列処理すべき個所にプラグマを記述していく実装スタイルであるため、ソースコードの視認性や保守性が悪くなりやすいという問題もある。TBBはテンプレートクラスライブラリという形で実装されているため、並列処理をカプセル化しやすく、保守性/再利用性の高いコードを記述できる。

図2 並列処理技術の方向性
図2 並列処理技術の方向性

TBBを用いた並列アプリケーションの設計と実装

 先に述べたように、TBBでは実行する処理と処理すべきデータを用意し、使用するアルゴリズムに対応するテンプレート関数にそれらを渡すというスタイルで並列処理を実装していく。以下では、典型的な並列処理を例に、TBBでの実装方法を紹介していこう。

 なお、本記事ではテスト環境として、CPUにCore i7 920(2.66GHz)、3GBのメモリを搭載したPCを使用した。OSはWindows Vista Home Premiumで、開発環境にはVisual Studio 2009 SP2およびParallel Studioを使用している。また、コンパイルオプションについてはデフォルトの設定(最適化オプションは「/O2」のみ)を使用している。

ヘッダーファイルのインクルードとタスクスケジューラの初期化

 TBBを利用する際には、使用するコンポーネントに応じたヘッダーファイルをincludeしておく必要がある。また、アルゴリズムテンプレート関数や後述するタスクスケジューラを使用する前には、「task_scheduler_init.h」内で定義されている「tbb::task_scheduler_init」クラスのオブジェクトを生成・初期化しておく必要がある。通常はリスト1のようにプログラムのスタートアップ時にこのオブジェクトを生成し、終了時にオブジェクトが破棄されるようにすれば良いだろう。

リスト1 TBBの利用前に必要なタスクスケジューラ初期化

#include "tbb/task_scheduler_init.h"

int main() {
    tbb::task_scheduler_init init;

    // 以下、アプリケーションの初期化とメイン処理を記述
 :
 :
 :
    return 0; // main()関数から抜けるとともに、initオブジェクトは破棄される
}

 また、TBBのヘッダーファイルおよびライブラリが適切に読み込まれるよう、ヘッダーファイルおよびライブラリの検索ディレクトリを適切に設定しておく必要がある。インテル Parallel Studioに付属するTBBを利用する場合、Parallel Composerの「Select Build Components」画面の「Use TBB」にチェックを入れておくだけでこれらの設定が完了する(図3、4)。

図3 インテル Parallel Studioを使用している場合、プロジェクトを右クリックして「Intel Parallel Composer」-「Select Build Components」でTBBを利用する設定が可能だ
図3 インテル Parallel Studioを使用している場合、プロジェクトを右クリックして「Intel Parallel Composer」-「Select Build Components」でTBBを利用する設定が可能だ
図4 「Use TBB」にチェックを入れると、自動的にTBBのヘッダーファイルおよびライブラリパスが検索対象に追加される
図4 「Use TBB」にチェックを入れると、自動的にTBBのヘッダーファイルおよびライブラリパスが検索対象に追加される