HPC/並列プログラミングポータル

 HPC/並列プログラミングポータルでは、HPC(High Performance Computing)プログラミングや並列プログラミングに関する情報を集積・発信しています。

新着トピックス

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

 C++で並列アプリケーションを実装するためのテンプレートライブラリとして、インテルがリリースしている「Intel Threading Building Blocks」(TBB)がある。TBBはインテル コンパイラーやインテル Parallel Studioといったインテルのコンパイラ製品に付属しているほか、オープンソース版も公開されている。本記事ではこのTBBの概要と、基本的な使い方を解説する。

 C/C++で並列アプリケーションを実装する手法として、並列化したい処理をOSのAPIを用いてマルチスレッド化する、もしくは並列プログラミングの規格である「OpenMP」を利用する、といったものが知られている。これらについては以前の記事でも紹介しているが、マルチスレッドを利用した実装は柔軟性がある一方で手間が掛かり、OpenMPは比較的手軽だが柔軟性に欠けるなど、それぞれに長所と短所がある。

 また、C++でアプリケーションを実装する場合、スレッドやOpenMPを利用した実装には別の困難さも生じてくる。1つはC++でのスレッドの扱いにくさ、もう1つは利用する関数やクラスが「スレッドセーフ」かどうか分かりにくい、という点だ。

 これらの問題を解決し、C++での見通しの良い並列処理実装を可能にするのが本記事で紹介する「Intel Threading Building Blocks」(以下、TBB)である。

Intel Threading Building Blocksが持つ機能

 TBBはC++で並列処理を記述するためのテンプレートクラスライブラリだ。インテルが開発し、かつては商用のライブラリとして販売されていたが、2007年にオープンソース化され、現在はGPL 2の下で公開されている。また、非オープンソースなプロダクトに利用できる商用版も引き続き提供されており、インテル コンパイラー製品やインテル Parallel Studio製品に同梱されているほか、単体でも購入が可能だ。現在の最新バージョンは2.2で、オープンソース版についてはthreadingbuildingblocks.orgからWindows/Linux/Mac OS X/Solaris向けのヘッダーファイルおよびバイナリを入手できる。

 TBBが提供する機能を簡単にまとめると、次のようになる。

  • データ群に対する反復処理を並列実装するためのテンプレートクラスやテンプレート関数
  • ストリーム処理/パイプライン処理を並列実装するためのテンプレートクラスやテンプレート関数
  • タスクベースの並列処理を実装するためのタスクスケジューラクラス
  • スレッドセーフなqueue/vector/mapクラス
  • スケーラブルなメモリアロケータ
  • mutexなどの排他処理機構

 並列処理を実装する場合、データや処理をどのように分割し、どのように実行するかがポイントとなる(図1)。たとえば多数のデータに対し同一の処理を行うような場合、データを分割して複数のスレッドに割り当て、同一の処理を並列実行させる方式が考えられる。また、ストリーム状の入力データを次々と処理していくような場合は、処理をパイプラインのように分割し、それぞれの行程を別スレッドで動作させることが考えられる。複数のコンポーネントが独立かつ非同期に処理を行うようなパターンでは、それぞれのコンポーネントごとにスレッドを割り当てるのが自然だ。TBBではこのような並列処理パターンそれぞれに対応するアルゴリズムやクラスが実装されており、アルゴリズムを選択し、ロジックとデータを用意するだけで簡単に並列処理を実装できる。

 また、並列化を行う場合には関数やクラスが「スレッドセーフ」かどうか、常に気を払わなければならない。並列化を行った個所でスレッドセーフでない関数を実行してしまうと、タイミングによってはデータの破壊や意図しない変更といった問題が発生するからだ。現在多くのC標準関数についてはスレッドセーフとなっているものの、C++でよく利用されるSTL(Standard Tempkate Library)についてはスレッドセーフであることは保証されていない。そのためTBBには、STLのqueueおよびvector、mapに相当するスレッドセーフなコンテナが用意されている。ただし、これらのスレッドセーフなコンテナはSTLのコンテナと比べると処理が遅い傾向があるため、必要な個所のみに利用するべきである。

 そのほか、アトミックな操作を行えるオブジェクトを作成するためのテンプレートクラスや、排他的な処理を行うためのmutex、スレッド化されスケーラブルなメモリアロケータなど、並列処理を実装する上で有用なコンポーネントなども含まれている。