レベル: 初級 Kane Scarlett, Editor, Multicore acceleration,
IBM
2008年 05月 09日 今回の Cell Broadband Engine™(Cell/B.E.) シリーズでは、Accelerated Library Framework (ALF) のバンドル化されたワークブロック分配と、ローカルメモリのサイズ制限からワークブロックが分割されたデータを格納することができない場合にタスクコンテキストを使って対応する方法を学びます。本記事は "ALF for Cell/B.E.Programmer's Guide and API Reference, Version 3.0" (参考文献を参照) を基にしています。
はじめに
本記事では、ALF のバンドル化されたワークブロック分配と、ローカルメモリのサイズ制限からワークブロックが分割されたデータを格納することができない場合にタスクコンテキストを使って対応する方法を学びます。
 |
もっと Fun with ALF
Fun with ALF シリーズでもっといろいろなことを学びましょう:
- "Fun with ALF: 第 1 回 大きな行列の加算" (developerWorks, March 2008) では、ALFを使って2つの大きな行列を加算する方法を(ホストデータ分割とアクセラレータ分割の例で)説明しています。
- "Fun with ALF: 第 2 回 I/Oデータの変換" (developerWorks, March 2008) で、16ビットの入力データを8ビットの出力バッファに変換するために、大きなルックアップテーブルとしてタスクコンテキストバッファをどのように使うのかを学びましょう。
- "Fun with ALF: 第 3 回 最小値と最大値の探索" (developerWorks, April 2008) では、タスクコンテキスを使って各タスクインスタンスで部分的な計算結果を保持し、そしてそれら部分結果を統合して最終結果を得る方法を示します。
- "オーバーラップI/Oバッファ (Overlapped I/O buffer)"では、オーバーラップI/Oバッファを行列の加算に使用する方法について調べています。
- "タスク依存関係 (Task dependency)"では、2つのステージを持つパイプラインアプリケーションを題材にタスクの依存関係を使う簡単なシミュレーションを行います。
そして、Cell/B.E.プログラミングを簡単にしてくれる、DaCS, BLASそしてその他の技術に関するFun withシリーズもみてみましょう。
|
|
この例では、2つの大きなベクトルの内積を計算します。式は以下のようになります:
図 1.2つの大きなベクトルの内積
内積の計算では、ベクトルの要素ごとの積を計算して累積する必要があります。1つのワークブロックがベクトルAi と Biの全てのデータを保持できる場合には、計算は単純です。しかし、ベクトルのサイズが非常に大きくて1つのワークブロックに収まらない場合、単純なアプローチではうまく動きません。
例えば、Cell/B.E.プロセッサでは、SPEには256KBのローカルメモリしかありません。長さが16384を超えると、2つの倍精度のベクトルを格納することができません (訳注:16384 * sizeof(double) * 2 = 16K * 8B * 2 = 256KB)。さらに、ダブルバッファリングやコードなどのためにも余分なメモリを必要としますので、それぞれ7500個の倍精度浮動小数点要素を持つ2つのベクトルを扱うのがせいぜいです(7500 * 8[size of double] * 2[two vectors] * 2[double buffer] でほぼ240KBのローカルメモリを消費します)。このような場合には、大きなベクトルは複数のワークブロックに分割しなくてはならず、それぞれのワークブロックは内積計算の部分的な結果を返すことになります。
ホストが各ワークブロックの部分結果を足し合わせて最終的な結果を得るという方法もあります。しかし、これはエレガントな方法ではなく、パフォーマンスの影響も受けます。よりよい方法は、この足し合わせをアクセラレータ側でかつ並列に行うものです。
この問題に対して、ALF は次の2つの実装方法を用意しています :
- タスクコンテキストとバンドル化ワークブロック分配を利用した実装。
- マルチユースワークブロックを利用した実装。タスクコンテキストまたはワークブロックパラメータ/コンテキストバッファを一緒に使用します。
この2つの実装のソースコードが以下のサンプルディレクトリにありますので比べてみましょう :
- タスクコンテキストとバンドル化ワークブロック分配を利用した実装は task_context/dot_prod ディレクトリ。
- マルチユースワークブロックと、タスクコンテキストまたはワークブロックパラメータ/コンテキストバッファを利用した実装は task_context/dot_prod_multi ディレクトリ。
タスクコンテキストとバンドル化ワークブロック分配の利用
この実装方法では、1つのベクルに対応するすべてのワークブロックがバンドルにまとめらます。1つのバンドルに対応するすべてのワークブロックは1つのタスクインスタンスにキューに入れられた順に割り当てられます。つまり、タスクコンテキストを中間結果の足し合わせに利用することができ、最後のワークブロックが処理されたら最終結果を書きだします。
新しいワークブロックバンドルが開始される度に、タスクコンテキスト内の足し合わせバッファを0に初期化します。
バンドル中の最後のワークブロックが処理されたら、タスクコンテキスト内の累積値を出力バッファにコピーし、結果格納エリアに書き出します。
図 2 は、この実装の概略図です。
図 2. タスクコンテキストとバンドル化ワークブロック分配の利用
マルチユースワークブロックと、タスクコンテキストまたはワークブロックパラメータ/コンテキストバッファの利用
2番目の実装方法は、マルチユースワークブロックと、ワークブロックパラメータ、コンテキストバッファによるものです。マルチユースワークブロックは、反復処理に似ています。アクセラレータ側のランタイムは、指定された反復回数に達するまで、繰り返しワークブロックを処理します。アクセラレータによるデータ分割を利用することで、ワークブロックの各反復において異なる入力データへのアクセスが可能です。
つまりアプリケーションは(ローカルメモリの制限によって)1つのワークブロックが扱えうことができるよりも大きなデータを扱えるということです。また、反復作業の間を通じてマルチユースワークブロックのパラメータとコンテキストバッファは保持されるので、タスクコンテキストバッファの代わりに累積値を格納するためのバッファとして利用できます。
図 3 はこの実装の概略図です。
図 3. マルチユースワークブロックと、タスクコンテキストまたはワークブロックパラメータ/コンテキストバッファの利用
まとめ
2つの実装方法—タスクコンテキストの利用と、マルチユースワークブロックの利用—は、どちらも同じように使えます。
参考文献 学ぶために
製品や技術を入手するために
議論するために
著者について  | 
|  | Kane Scarlett は技術ジャーナリスト/アナリストとして20年の経験があり、National Geographic, Population Reference Bureau, Miller Freeman, IDGで記事を書いています。また、恐れ多くも各種のジャーナル誌、JavaWorld、LinuxWorld、そしてもちろんdeveloperWorksへの記事の管理、編集、執筆を行っています。 |
記事の評価
|