ストリーム・プロセッシング
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2023/08/21 02:53 UTC 版)
ストリーム・プロセッシングの考察
この節は検証可能な参考文献や出典が全く示されていないか、不十分です。(2016年10月) |
この節には独自研究が含まれているおそれがあります。 |
この記述の時点で (2005年9月12日)、ストリーム・プロセッシングに関する入手可能な文書は非常にとぼしく、ごく少数の機関しかこのモデルの潜在的なパワーを理解していない。スタンフォード大学は歴史的に、これに関する様々なプロジェクトに関係している。Stanford Shading languageに始まり、さらに進んでは、柔軟なスタンドアロンのストリームプロセッサImagineが行われた。それらのプロジェクトの結果、このパラダイムの潜在的な可能性の大きさが明らかになり、より大規模なプロジェクトMerrimacが開始された。Merrimacは、ストリームベースのスーパーコンピュータであり、現在[いつ?]研究が続行されている。 AT&Tで認識されているのは、ストリーム処理を拡張したプロセッサの広範な採用により、GPUが速度と機能の両面において急速に進化した点である[1]。
データの依存関係と並列性
ストリームプログラミングモデルの大きな長所は、独立かつ局所的なデータの使い方を定義するカーネルから生まれる。 カーネルの動作は、基本的なデータの単位を、入出力両方で定義する。これにより、ハードウェアがうまくリソースを割り当て、グローバルの I/O をスケジュールできる。 通常プログラミングモデルからは見えないが、ストリームプロセッサ(少なくともGPUでは)I/O の動作は相当に進歩した物であるようだ。I/O 操作自体も通常パイプライン化されており、チップの機構によりレイテンシの隠蔽を補助する。 データ単位の定義は通常カーネルにおいて明示的であり、すなわち十分定義された入力 (たとえば構造体の使用が推奨されている) と出力を期待されている。いくつかの環境では、出力の値は固定である (たとえばGPUでは、特に条件を緩和しなければ固定された出力情報が存在する)。 それぞれの計算ブロックを明確に独立で定義づけられたものにすることで、まとまった量の読み込みや書き込みの操作が、キャッシュやメモリバスの効率性を著しく向上させる。
データの局所性もカーネルにおいて明示的である。この概念は、通常カーネル局所性と呼ばれ、単一のカーネルの呼び出しのため寿命が短い値をすべて識別する。すべての一時的なデータは単純にそれぞれのカーネルの呼び出しに対して局所的であると仮定することで、ハードウェアやソフトウェアはこれらを高速なレジスタに割り当てることができる。このことは、利用できる並列性の度合いと厳密に関わっている。
各カーネルの内部では、個々の生産-消費の関係をくくりだすことができる(カーネルが次々と連結されていく場合には、この関係はモデルによって与えられる)。 これにより、カーネルBがカーネルAの出力を必要とするとき、AはBが実行できるようになる前に完了していなければならないことは明らかである(少なくとも使用されているデータ単位については)ため、スケジューリング上の決定を簡単に行うことができる。 Imagine チップのオンボードストリームコントローラーモジュールは、カーネルの依存関係(コンパイラより与えられる)のスコアボードを保った状態でカーネルのロードをランタイムにハードウェアで行い、ストールを最小化するアウトオブオーダー実行ができるようにする。これは、高性能の演算処理に置ける新たなパラダイムである。Cellがこれをたとえば複数の SPE 間でデータを回送しながら行うということを示す情報もある。これと比較して、Imagine は純粋なSIMDマシンであり、クラスタ間の通信やカーネルの実行は常に明示的で、Cell のような MIMD マシンと比べてシリコンの面積も小さい。
昨今[いつ?]、CPU ベンダーがマルチコアやマルチスレッディングを推進している。このトレンドは平均的なユーザーにとっては役立つ物になるが、標準的な CPU が並列計算においてストリームプロセッサの性能に近づく余地はないだろう。
二つのカーネルインスタンスの並列性はスレッドレベル並列性と類似している。 各カーネルの内部で、さらに命令レベル並列性を用いることも可能である。 タスクレベルの並列性 (オーバーラップしたI/Oなど) は起こりうる。カーネルインスタンスを何千個も持つことはたやすいが、同数のスレッドを持つことは単純に不可能である。これがストリームの力である。
プログラミングモデルに関して
SIMD プログラミングモデルの欠点の一つは、構造体の配列 (AoS) と配列の構造体 (SoA) の問題である。プログラマーはデータ構造の定義にデータの論理的な意味を反映したがる。例えば:
// 三次元空間上の微粒子
struct particle_t {
float x, y, z; // 配列にもなっていない!
byte color[3]; // チャンネルあたり8bitで、RGBのみ考えている
float size;
// ...以下、それ以外の属性が続く...
};
このような構造体はメモリにうまく配置されるように、配列にアセンブルされることになる。 これがAoSである。この構造体がメモリに配置される際、コンパイラはインターリーブされたデータを生成する。つまりすべての構造体が連続しているが、一つの構造体の例えば "size" 属性と、次の構造体の同じ属性には固定値のオフセットが存在する。 オフセットは構造体の定義に依存する(ここでは考慮していないコンパイラの配置ポリシーなどもある)。 他の問題もある。例えば、三つの位置変数は同じように SIMD 化することができない。なぜなら連続したメモリ空間に配置されるかどうかが不明なためである。SIMD 演算が動作するようにするには、パックされた配置とするか、最低でも配列内になければならない。 更なる問題は、"color"と"xyz"が3要素のベクトル量として定義されている点である。SIMD プロセッサは通例4要素の演算のみサポートする(いくつかの例外はあるが)。
この種の問題や制約は、通常の CPU での SIMD による高速化を非常に汚いものにしてしまう。 SoAでの解決策は以下のようになるだろう:
struct particle_t {
float *x, *y, *z;
byte *colorRed, *colorBlue, *colorGreen;
float *size;
};
ここで"*"はC言語でいうところのポインターである。要するに、別途割り当てることになる配列の先頭へのアドレスがここに入る。読者がJavaプログラマーなら"*"を"[]"で読み替えてくれればだいたい同じ意味になる。 ここでの問題点は、様々な属性がメモリ上に分散してしまうことである。キャッシュミスを発生させないようにするため、すべての "red" を書き換え、次にすべての "green" とすべての "blue" を書き換えなければならない。結果的にそれほど悪くないようにも見えるが、ストリームプロセッサが提供するものと比べると制約が強すぎる。
ストリームプロセッサに対しては、構造体を使うことが推奨されている。アプリケーションの観点から見ると、すべての属性が多少柔軟性を持って定義できる。 GPU を例とすると、多数の属性(最低でも16の)が利用できる。各々の属性について、アプリケーションはコンポーネントの数とフォーマット(現状は基本型のみがサポートされている)を宣言できる。次に、ある要素が点在しているのか連続しているのかを定義しながら、様々な属性がメモリブロックに割り当てられ、事実上インターリーブされたデータ形式を許容している。 GPU がストリームの処理を開始する際、すべての属性を単一のパラメータセット(大抵は、構造体や"魔法のグローバル変数"のような形式である)に集め、演算を実行し、次の処理(あるいは演算結果の回収)のためにメモリのどこかの領域に結果をばらまく。
まとめると、アプリケーション側にはより大きな柔軟性があるが、ストリームプロセッサ側では非常に秩序だった形式である。
汎用的なプロセッサのアーキテクチャ
歴史的には、外部メモリのバンド幅がわずかしか向上しないのに対して、CPU は性能が増大しつづけるため、複数の階層に渡ったメモリアクセスの最適化を実装してきた。このギャップが広がるにつれて、ダイの面積の非常に大きな部分がメモリのレイテンシを隠蔽するためだけに使用されている。わずかな ALU に対してデータと命令をフェッチすることが高価であるため、非常にわずかなダイの面積しか実際の数値演算処理を行う機構に使用されていない (大まかな見積もりで、たとえば 10% 以下程度と思えばよい)。
ストリームプロセッサでも同様の機構は存在するが、新しいプログラミングモデルのおかげで、(計算を行わない) 管理部分にのみ使用されるトランジスタの量は実際には非常に少ない。
システム全体の観点からストリームプロセッサは通常制御された環境の中に存在する。GPU は拡張ボードとして存在している (これは Imagine にも当てはまるようだ)。CPU はシステムリソースの管理や、アプリケーションなどを動作させる雑多な作業を行っている。
ストリームプロセッサは、通常、高速で効率のよい独自方式のメモリバスに接続されている(クロスバースイッチが現在[いつ?]では一般的で、かつてはマルチバスが採用されていた)。メモリレーンの正確な量はマーケットの範囲によって異なる。執筆の時点では、まだ (エントリーレベルでは) 64bit幅でインターコネクトがある。ほとんどのミッドレンジのモデルは 128bitのクロスバースイッチのマトリクス (4か2セグメント) を持っており、ハイエンドのモデルは膨大なサイズのメモリ (512MB程度まで) を、若干低速なクロスバースイッチを介して256bit幅で接続している。一方、PentiumやAthlon64などの標準的なプロセッサは、64bit幅のデータバスをひとつ持っているだけである (訳注:2005年時点?)。
メモリアクセスのパターンもかなりの部分予測可能である。配列は存在するが、カーネルの呼び出しにおいて、メモリの配置は固定的である。複数レベルのポインタによる間接参照にほぼ対応するのはindirection chainであるが、これは最終的に(ストリーム内の)特定のメモリ領域を読み書きすることが保証されているものである。
ストリームプロセッサの実行ユニット (ALUクラスタ) はその SIMD 的な性質から、読み書きの操作はまとめて行われることになっており、メモリは低レイテンシよりも高バンド幅に最適化される (これはたとえば、RambusとDDR SDRAMの違いである)。これはメモリバスの調停を効率的にする。
ストリームプロセッサのほとんど (90%) の作業はチップ内で行われ、全体のデータの1%のみがメモリに格納される。これが、カーネルの一時的な記憶と、依存関係を明らかにすることにより得られるものである。
内部的には、ストリームプロセッサは通信や管理用の機能を備えるが、興味深いのは Stream Register File (SRF) である。これは概念的にはストリームデータを外部のメモリにバルク転送するために格納する大規模なキャッシュである。各種の ALU 向けのキャッシュのようなソフトウェア制御の機構と同じく、SRF はすべての ALU クラスタ間で共有される。Stanford の Imagine チップにおいて基本となる考え方と、ここで行われた革新的な技法は、コンパイラに高度なフロー解析を施し、SRF を最適にパックし、DMA を自動化して、カーネルとデータの依存関係が、プログラミングモデル全体を通じて明らかであることである。ハードウェアは、カーネルのアウトオブオーダー実行を可能にするためのランタイムの同期処理を行うことができる。一般に、キャッシュと DMA の管理は処理時間のほとんどを使ってしまうようなものであるが、ストリームプロセッサ (少なくともImagine) は、これを完全に自動化する。Stanford で行われたテストでは、メモリのスケジューリングにおいて、手間をかけて手動でチューンした場合より、コンパイラが同等かそれ以上の結果を出せることを示した。
クラスタ間の通信が稀であることが前提である場合のみ、クラスタは多数存在することができることが立証されている。しかし、内部的にクラスタ間の通信が多数ある場合には、効率が高いことが求められ、各クラスタが少数の ALU しか効率的に使えない。
ALU がデータをフェッチした状態に保つには、各 ALU はローカルレジスタファイル (LRF) を持つ必要があり、基本的にはこれらが使用可能なレジスタである。
この3階層形式のデータアクセス形態は、低速なデータメモリから一時的なデータを駆逐し、シリコン上の実装を効率的にし、消費電力を低減させる。
Hardware-in-the-loop 問題
1桁大きなスピードの向上が期待できる (ストリーミングの方法で計算を行えば、メインストリームのGPUでさえ) が、すべてのアプリケーションが恩恵を受けられるわけではない。通信のレイテンシが通常最大の問題である。PCI Expressが双方向通信を改善させたが、GPU (あるいは、一般的なストリームプロセッサ) を動作させるには、まだ長い時間が必要と思われる。 これは、小さなデータセットに対して使うのは逆効果であることを意味する。ストリームアーキテクチャは小さなストリームに対してペナルティがあり、この振る舞いはshort stream effectとして公式に認知されている。これは、基本的にはカーネルを切り替えることが高価な操作であるために起こる。
パイプライン化は、ストリームプロセッサでは定着した方法であり、GPU では 200 ステージを超えるパイプラインを備える。ある設定を切り替えるためのコストは、変更される設定に依存するが、基本的に高価だとみなされている。切り替えのコストを下げるために努力が行われているが、そうすぐに現実にならないとも予測されている。こうした問題をパイプラインの様々なレベルで避けるため、"uber shaders"や"texture atlases"のような多数のテクニックが導入されている。これらのテクニックは GPU の性質からゲームに向いたものだが、その考え方は、汎用のストリームプロセッシングでも興味深い。
固有名詞の分類
並列コンピューティング |
Pluribus SIMD ストリーム・プロセッシング IWarp Linda |
- ストリーム・プロセッシングのページへのリンク