インテル スレッディング・ビルディング・ブロック

―マルチコア時代のC++並列プログラミング

[cover photo]
TOPICS
Programming , C/C++
発行年月日
PRINT LENGTH
360
ISBN
978-4-87311-355-5
原書
Intel Threading Building Blocks
FORMAT
PDF
Ebook
3,850円
Ebookを購入する

マルチコア時代の並列プログラミングを独習できる入門書。オープンソースとして公開された話題のインテル スレッディング・ビルディング・ブロック(Intel Threading Building Blocks:TBB)は、C++のSTLを拡張した並列処理用のテンプレート・ライブラリー。TBBがスレッド管理を抽象化してくれるのでプログラマーはアルゴリズムに集中できる。本書ではTBBを使ったコードのスレッド化についてサンプルを示しながらわかりやすく解説する。マルチコア/マルチスレッド用に最適化されたスケーラブルなアプリケーションを開発するアーキテクトおよびプログラマー必携の一冊。TBB 1.0、1.1、2.0対応。

関連ファイル

正誤表

ここで紹介する正誤表には、書籍発行後に気づいた誤植や更新された情報を掲載しています。以下のリストに記載の年月は、正誤表を作成し、増刷書籍を印刷した月です。お手持ちの書籍では、すでに修正が施されている場合がありますので、書籍最終ページの奥付でお手持ちの書籍の刷版、刷り年月日をご確認の上、ご利用ください。

正誤表 - 2008年4月掲載(2刷以降は修正済み)

■P.2 下から4行目
  • 【誤】スレッド・プリミティブから、
  • 【正】スレッドAPIから、
■P.3 上から15行目
  • 【誤】もちろん、ハードウェアに近いスレッドを直接制御する方法では、
  • 【正】ハードウェアに近いスレッドを直接制御する方法では、
■P.4 上から14行目
  • 【誤】スレッディング・ビルディング・ブロックは、一般的なプログラミングを使用
  • 【正】スレッディング・ビルディング・ブロックは、汎用プログラミングを使用
■P.4 上から16行目
  • 【誤】12章で定義されている一般的なプログラミングを使用します。
  • 【正】12章で定義されている汎用プログラミングを使用します。
■P.5 下から7行目
  • 【誤】C言語の生来の仲間
  • 【正】C言語の生来の機能
■P.9 本文の上から9行目
  • 【誤】これまで並列プログラミングに深くかかわってきた場合でも、
  • 【正】また、これまで並列プログラミングに深くかかわってきた場合でも、
■P.12 上から2行目
  • 【誤】データの並列処理は結局、
  • 【正】データ並列処理は、
■P.12 上から3行目
  • 【誤】データを共有してリンクされる、異なる独立したタスクを意味します。
  • 【正】データ共有してリンクされる異なる独立したタスクを意味します。
■P.12 上から10行目
  • 【誤】そのほとんどは特殊なパイプライン処理として言及されます。
  • 【正】そのほとんどは特殊なパイプライン処理であることがわかります。
■P.13 上から3行目
  • 【誤】この一連のタスクのために6人のグループを集めた場合、
  • 【正】この一連のタスクに6人の作業員を集めた場合、
■P.14 上から9行目
  • 【誤】図2-7は、各ステップで行う作業量をサイズで示しています。
  • 【正】図2-7は、各ステップで行う作業量をバーの長さで示しています。
■P.14 図2-7
  • 【誤】p14NG.JPG
  • 【正】P14OK.JPG
■P.21 下から11行目
  • 【誤】そのためにも、この根本的な実装の意味を理解しておく必要があります。
  • 【正】そのためにも、この基本的な実装の意味を理解しておく必要があります。
■P.22 上から3行目
  • 【誤】電子メールプログラムとWebブラウザーが通信できる場合、
  • 【正】電子メールプログラムとWebブラウザーが通信するような場合、
■P.36 上から17行目
  • 【誤】floatを指すことではっきりします。
  • 【正】floatを指すことで明示します。
■P.117 上から11行目
  • 【誤】2章では、排他制御とロックを紹介し、デッドロックと競合状態について説明し、スレッドセーフなプログラムには何が必要であるか指摘しました。
  • 【正】2章では、排他制御とロック、そしてデッドロックと競合状態について説明し、スレッドセーフなプログラムには何が必要であるか指摘しました。
■P.185 下から10行目
  • 【誤】2章では、排他制御とロックを紹介し、デッドロックと競合状態について説明して、スレッドセーフなプログラムには何が必要かを指摘しました。
  • 【正】2章では、排他制御とロック、そしてデッドロックと競合状態について説明し、スレッドセーフなプログラムには何が必要であるか指摘しました。

正誤表 - 2008年5月掲載(3刷以降は修正済み)

■P.75 下から14行目(例4-5)
  • 【誤】// バッファーの最後の1つ前の文字へのポインター
  • 【正】// バッファーに格納される最終文字の次の文字へのポインター
■P.95 表5-2の最後の行
  • 【誤】R::iterator R::end() const 範囲の過去の最後の項目
  • 【正】R::iterator R::end() const 範囲の最後にある項目の次の項目
■P.105 表5-5の最後の行
  • 【誤】R::iterator R::end() const 範囲の過去の最後の項目
  • 【正】R::iterator R::end() const 範囲の最後にある項目の次の項目
■P.221 下から1行目(例11-24)
  • 【誤】//! ウィンドウの最後の1つ前の数
  • 【正】//! ウィンドウの最後の数の次の数

正誤表 - 2011年12月掲載(4刷以降は修正済み)

■P.viii 追加
監訳者追記
 本書が出版されて4年が経ちました。TBBも改良が行われており、2011年12月時点でバージョン4.0がリリースされています。本書が出版された当時のTBBはバージョン2.0でしたので、いくつかの機能が新たに追加されています。最新の情報についてはTBBのWebサイト(http://threadingbuildingblocks.org/)を参照ください。もちろん、最新版においても本書で紹介する内容は有効ですので引き続き活用してください。
  2011年12月
  菅原 清文

■P.15 下から5行目
  • 【誤】クアッドコア
  • 【正】デュアルコア
■P.24 下から13行目
  • 【誤】明示的な同期とアトミック操作では不十分な場合は、
  • 【正】暗黙の同期とアトミック操作では不十分な場合は、
■P.35 下から3行目
  • 【誤】これは、T型を超える1次元の反復空間を示します。
  • 【正】これは、T型1次元空間上の反復空間を示します。
■P.50 下から6行目
  • 【誤】反復空間は、リニアである必要はありません。
  • 【正】反復空間は、1次元である必要はありません。
■P.52 13行目
  • 【誤】結合演算
  • 【正】可換演算
■P.52 16行目
  • 【誤】● y_i = y_{i-1} \oplus i
  • 【正】● y_i = y_{i-1} \oplus x_i
■P.53 9行目
  • 【誤】Body( T y_[], const T x_[] ) : reduced_result(0), x(x_), y(y_) {}
  • 【正】Body( T y_[], const T x_[] ) : reduced_result(id_{\oplus}), x(x_), y(y_) {}
■P.54 3行目
  • 【誤】結合演算
  • 【正】可換演算
■P.54 4行目
  • 【誤】使用される結合に依存して
  • 【正】使用される演算に依存して
■P.54 5行目
  • 【誤】再結合は
  • 【正】再可換は
■P.54 下から22行目
  • 【誤】Body( T y_[], const T x_[] ) : sum(0), x(x_), y(y_) {}
  • 【正】Body( T y_[], const T x_[] ) : sum(id_{\oplus}), x(x_), y(y_) {}
■P.54 下から16行目
  • 【誤】temp = temp x[i];
  • 【正】temp = temp \oplus x[i];
■P.54 下から10行目
  • 【誤】sum(id) {}
  • 【正】sum(id_{\oplus}) {}
■P.54 下から9行目
  • 【誤】{ sum = a.sum sum;}
  • 【正】{sum = a.sum \oplus sum;}
■P.66 下から4行目
  • 【誤】結合演算
  • 【正】可換演算
■P.66 下から4行目
  • 【誤】シーケンスx_0, x_1, ... x_{n-y}上の
  • 【正】シーケンスx_0, x_1, ..., x_{n-1}上の
■P.71 下から8行目
  • 【誤】ItemStream stream;
  • 【正】ItemStream stream(root);
■P.160 下から6行目
  • 【誤】set_ref_count(2);
  • 【正】c.set_ref_count(2);
■P.161 下から20行目
  • 【誤】FibTask& a = *new( c.allocate_child() ) FibTask(n-2,&c.x);
  • 【正】// 変更前: FibTask& a = *new( c.allocate_child() ) FibTask(n-2,&c.x);
■P.161 下から14行目
  • 【誤】set_ref_count(2);
  • 【正】c.set_ref_count(2);
■P.196 下から11行目
  • 【誤】0≦1<nの場合に、
  • 【正】0≦i<nの場合に、
■P.216 12行目
  • 【誤】結合演算
  • 【正】可換演算
■P.310 下から13行目
  • 【誤】キャッシュでホットと呼ばれます。
  • 【正】キャッシュ上のホットなデータと呼ばれます。

目次

日本語版の出版に寄せて
監訳者まえがき
推薦の言葉 −本書に対する賞賛の声
本書に寄せて
TBB開発責任者から
まえがき

1章 なぜスレッディング・ビルディング・ブロックなのか?
    1.1 概要
    1.2 利点
        1.2.1 ネイティブスレッド/MPIとの比較
        1.2.2 OpenMPとの比較
        1.2.3 再帰分割、タスクスチールとアルゴリズム

2章 並列思考
    2.1 並列思考の要素
    2.2 分解
        2.2.1 データの並列処理
        2.2.2 タスクの並列処理
        2.2.3 パイプライン化(タスクとデータ両方の並列処理)
        2.2.4 混合ソリューション
        2.2.5 並列処理の実現
    2.3 スケーリングとスピードアップ
        2.3.1 アプリケーションにどれだけの並列処理があるか?
    2.4 スレッドとは?
        2.4.1 スレッドのプログラム
        2.4.2 並列状態における安全性
    2.5 排他制御とロック
    2.6 正当性
    2.7 抽象化
    2.8 パターン
    2.9 直感による判断

3章 基本的なアルゴリズム
    3.1 ライブラリーの初期化と終了
    3.2 ループの並列化
        3.2.1 parallel_for
        3.2.2 parallel_reduce
        3.2.3 高度なトピック:異なる種類の反復空間
        3.2.4 parallel_scan
    3.3 再帰的な範囲指定
        3.3.1 分割可能コンセプト
        3.3.2 Rangeコンセプト
        3.3.3 Partitionerコンセプト
        3.3.4 再帰的なテンプレート
    3.4 ループのまとめ

4章 高度なアルゴリズム
    4.1 ストリーム用の並列アルゴリズム
        4.1.1 完了までの並列化:parallel_while
        4.1.2 組み立てラインでの作業:パイプライン
        4.1.3 parallel_sort

5章 コンテナー
    5.1 concurrent_queue
        5.1.1 デバッグ目的のconcurrent_queue上での反復
        5.1.2 キューを使用すべきではない状況
    5.2 concurrent_vector
        5.2.1 ベクトル全体の操作
        5.2.2 並列操作
        5.2.3 並列反復
        5.2.4 キャパシティー
        5.2.5 イテレーター
    5.3 concurrent_hash_map
        5.3.1 HashCompareの詳細
        5.3.2 テーブル全体の操作
        5.3.3 同時アクセス
        5.3.4 並列操作:find、insert、erase
        5.3.5 並列反復
        5.3.6 キャパシティー
        5.3.7 イテレーター

6章 スケーラブルなメモリー割り当て
    6.1 制限
    6.2 メモリー割り当ての問題
    6.3 メモリー・アロケーター
        6.3.1 どのライブラリーをアプリケーションにリンクすればいいか
        6.3.2 C++ STLテンプレート・クラスへのアロケーター引数の使用
    6.4 malloc、new、deleteの置換
        6.4.1 malloc、free、realloc、callocの置換
        6.4.2 newとdeleteの置換
        6.4.3 Allocatorコンセプト
        6.4.4 モデル型

7章 排他制御
    7.1 排他制御を使用すべき状況
    7.2 mutexの概要
        7.2.1 mutexの特性
        7.2.2 リーダー/ライターmutex
        7.2.3 アップグレード/ダウングレード
        7.2.4 ロックの問題
    7.3 mutexのインターフェイス
        7.3.1 Mutexコンセプト
        7.3.2 ReaderWriterMutexコンセプト
    7.4 アトミック操作
        7.4.1 atomic<T>にコンストラクターがない理由
        7.4.2 メモリーの一貫性とフェンス

8章 タイミング

9章 タスク・スケジューラー
    9.1 タスクベースのプログラミングが適切ではない場合
    9.2 ネイティブスレッドより優れている点
        9.2.1 オーバーサブスクリプション
        9.2.2 フェア・スケジューリング
        9.2.3 コーディングのオーバーヘッド
        9.2.4 ロード・インバランス
        9.2.5 移植性
    9.3 ライブラリーの初期化
    9.4 フィボナッチ数のサンプルプログラム
    9.5 タスク・スケジューリングの概要
    9.6 タスク・スケジューリングの動作
    9.7 推奨するタスク回帰パターン
        9.7.1 ブロックスタイルと子
        9.7.2 継続渡しスタイルと子
    9.8 スケジューラーの活用
        9.8.1 再帰連鎖反応
        9.8.2 継続渡し
    9.9 タスク・スケジューラーのインターフェイス
    9.10 タスク・スケジューラーのまとめ

10章 成功への秘訣
    10.1 成功への重要なステップ
    10.2 緩和直列実行
    10.3 メソッドとライブラリーの安全な並列化
    10.4 デバッグとリリース
    10.5 効率に関する考察
    10.6 デバッグ機能を利用する
        10.6.1 TBB_DO_ASSERTマクロ
        10.6.2 TBB_DO_ASSERTを含むプログラムを出荷しない
        10.6.3 TBB_DO_THREADING_TOOLSマクロ
        10.6.4 デバッグ・ライブラリーとリリース・ライブラリー
    10.7 その他のスレッドパッケージとの併用
    10.8 命名規則
        10.8.1 tbb名前空間
        10.8.2 tbb::internal名前空間
        10.8.3 _ _TBBプリフィックス

11章 コードの例題
    11.1 Aha !(なるほど!)
    11.2 その他の重要なポイント
    11.3 parallel_forのコードの例題
        11.3.1 ParallelAverage
        11.3.2 地震波
        11.3.3 行列乗算
        11.3.4 ParallelMerge
        11.3.5 SubstringFinder
    11.4 ライフゲーム
        11.4.1 実装
        11.4.2 オートマトン
        11.4.3 オートマトン:実装
        11.4.4 アプリケーションの拡張
        11.4.5 参考文献
    11.5 parallel_reduceのコードの例題
        11.5.1 ParallelSum
        11.5.2 粒度を指定する必要のないParallelSum
        11.5.3 ParallelPrime
    11.6 CountStrings: concurrent_hash_mapの使用
    11.7 クイックソート:タスクスチールの視覚化
    11.8 高速な行列乗算(Strassen)
    11.9 高度なタスク・プログラミング
        11.9.1 メインプログラムで並列に大きなタスクを開始する
        11.9.2 2つの出入り口:パイプラインの同じタスクから2つ供給する
    11.10 パケット処理パイプライン
        11.10.1 インターネット・デバイス用の並列プログラミング
        11.10.2 ローカル・ネットワーク・ルーターの例
        11.10.3 ローカル・ネットワーク・ルーター用にパイプライン化されたコンポーネント
        11.10.4 実装
        11.10.5 フィルタークラス
    11.11 メモリー割り当て
        11.11.1 newとdeleteの置換
        11.11.2 malloc、calloc、realloc、freeの置換
    11.12 ゲームのスレッド化のコードの例題
        11.12.1 スレッド化アーキテクチャー:物理計算+レンダリング
        11.12.2 スケーラビリティーで重要なこと
        11.12.3 フレームループ
        11.12.4 ドメイン分解データ構造の必要性
        11.12.5 スレッドではなくタスクで考える
        11.12.6 ロードバランスとタスクスチール
        11.12.7 物理計算スレッド間の同期
        11.12.8 コードの例題の実際のゲームへの統合
        11.12.9 パフォーマンスの測定方法
    11.13 相互作用の物理計算と更新のコード
    11.14 オープン・ダイナミクス・エンジン(Open Dynamics Engine)
        11.14.1 hotspotの調査
        11.14.2 最初のソリューションの改善
        11.14.3 コードの例題

12章 歴史と関連プロジェクト
    12.1 ライブラリー
    12.2 言語
    12.3 プラグマ
    12.4 汎用プログラミング
        12.4.1 汎用プログラミングのコンセプト
        12.4.2 汎用プログラミングの擬似署名
        12.4.3 汎用プログラミングのモデル
    12.5 キャッシュ
    12.6 タイムスライスのコスト
    12.7 ラムダ関数の紹介
    12.8 参考文献

索引