世界のスーパーコンピュータとそれを動かす人々


2月 17, 2014

アクセラレータプログラミングの未来

HPCwire Japan

Kamil Rocki and Martin Burtscher

最新のスーパーコンピュータの多くは、2013年11月のTOP500リストよると2つの最速システムを含め、アクセラレータに基づいている。アクセラレータはまた、PCで広く普及し、ハンドヘルドデバイスでさえも使われ始め、そしてアクセラレータプログラミングへの関心をさらに高めるであろう。

この広範な採用は、高性能、優れたエネルギー効率、および低価格の結果である。例えば、どちらも2012年3月にリリースされたXeon E5-2687W CPUとGTX 680 GPUを比較すると、GPUが4倍安いことから始まり、8倍の単精度性能と4倍以上のメインメモリ帯域幅、そして30倍以上のドルあたりの性能と6倍以上のワットあたりの性能を提供出来る事がわかる。これらの数値に基づくと、アクセラレータは、どこでもいつでも使用すべきである。では、なぜそうならないのか?

アクセラレータには2つの重要な難しさがある。最初に、それらは十分な並列性、データの再利用、およびそれらの制御フローとメモリアクセスパターンの規則性を有する特有なプログラムにおいて、明白なタイプのプログラムのみ効率的に実行することができる。2番目に、非常に広い平列度、むき出しのメモリ階層、ロックステップ実行、そしてメモリアクセスの結合などのアーキテクチャ的な不均衡のため、CPUに比べてアクセラレータのための効果的なソフトウェアを書くことが難しい。いくつかの新しいプログラミング言語やそれの拡張機能は、様々な角度でこれらの側面を隠すように提案されていて、それ故にアクセラレータをプログラムすることを簡単にできる。

現在では最も顕著なタイプのアクセラレータで、非画像処理プログラムを高速化するためにGPUを使う最初の試みでは、複雑で効率悪く、限られた制御フローと整数演算の無いものだけをサポートしたシェーダーコードの形で計算を表現することが必要だった。徐々に、これらの制約は緩和され、GPUをより多目的用途なコンピューティングデバイスにし、非グラフィック専門家がそれらをプログラムすることが可能になった。この方向の最大のステップは、CUDAプログラミング言語のリリースに付属したことである。これは、ライブラリ関数だけでなく追加の修飾子やキーワードと、カーネルと呼ばれるGPU上でコードセクションを起動するためのメカニズムを伴ってC/C++を拡張する。

それが独自のものであるという事実と良好なCUDAコードを書く複雑さを併せ持つCUDAの急速な普及は、OpenCL、C++ AMPおよびOpenACCなど、アクセラレータのための幾つかの他のプログラミングアプローチ作成の引き金となった。OpenCLは、CUDAの非独占の対応であり、多くの大企業によって後援されている。これは、NVIDIA GPUに限定せず、AMD GPU、マルチコアCPU、MIC(Intel Xeon Phi)、DSPおよびFPGAをサポートし、極めて移植性に優れる。しかし、ただCUDAのように、それは非常に低いレベルで、ソフトウェア開発者は明示的にデータの移動を調整し、変数をメモリ階層の何処に置くか選択し、コード内で並列処理を手動で表現する必要がある。C++ Accelerated Massive Parallelism(C++ AMP)は、中間レベルで動作する。これは、C++で直接データ並列処理を表現することができ、プログラマからのすべての低レベルコードを隠蔽する。並列「for each」文は、並列コードをカプセル化する。C++ AMPは、Windowsに拘束され、CPUを(まだ)サポートしておらず、そして起動時のオーバーヘッドの影響を受け、短期実行コード部分を加速するためには実用的ではない。

OpenACCは、プログラマが、GPUへそれらをオフロードすることによって、例えば、コードセクションを加速するようにコンパイラに通知するプラグマを用いてコードに注釈を付けることができる非常に高レベルなアプローチである。考え方は、OpenMPがCPUプログラムを並列化するために使用することができる方法と同様である。事実、その2つのアプローチを合併するために進行中の活動がある。OpenACCは、依然成長しており、現在、わずか数コンパイラだけでサポートされている。

アクセラレータプログラミングをこの先開発する方法を予測することは、他のアクセラレーションハードウェアが過去にどのように進化したのか調べるために有用かも知れない。例えば、一部の初期のハイエンドPCは、浮動小数点(FP)演算を加速するためにコプロセッサと呼ばれる特別なチップを含んでいた。その後、このコプロセッサは、同一ダイ上でCPUと組み合わされ、今では完全に整数演算コアと統合されている。唯一、FPレジスタとのALUが分離され残っている。最近追加された非常に多くのSIMDサポート(MMX、SSE、AltiVecとAVXを含む)は、分離されたチップ上で起動せず、今も完全にコアに統合されている。浮動小数点命令のように、SIMD命令は別々のレジスタとALUを操作する。

興味深いことに、これら2つのタイプの命令のプログラマの観点は、驚くほど異なっている。浮動小数点演算とデータタイプは、だいぶ前に標準化(IEEE 754)され、今では遍在している。これらは、通常の算術演算と内蔵の32ビット単精度および64ビット倍精度のタイプを介して高レベル言語で直接利用可能である。対照的に、SIMD命令のための標準化は存在せず、その存在は、プログラマから大部分隠​​されている。それはコードの「ベクトル化」をコンパイラに任せると、これらの命令を採用する。SIMD命令を明示的に使用したい開発者は、移植性の無いコンパイラ固有のマクロに頼らなければならない。

GPUとMICは、SIMDのような実行を介してその高い性能を得るので、アクセラレータは、FP命令のサポートよりも、SIMD命令の進化を追い求める可能性が高いと思う。SIMDへの別の類似性、そしてCUDAが大成功した重要な要因は、CUDAはGPUハードウェアのSIMD的側面を隠し、スカラーデータ要素ではなくベクトルで命令を包んで動作する個別のスレッドの観点でプログラマが考えることを可能にした。したがって、アクセラレータもまた、明らかにCPUチップ上に移されるが、クセラレータのハードウェアがサポートするデータタイプをプログラマが明示的に利用出来ないと、彼らのコードをシームレスにCPUコードと織り交ぜる事は出来ないと推測する。

一部のアクセラレータは、すでにAMDのAPU(Xbox Oneで使用されるように)、HDグラフィックスを持つIntelのプロセッサとNVIDIAのTegra SOCを含め、同一チップ上に従来のプロセッシングコアと一緒に組み合わされている。しかし、それは、FPとSIMD命令で可能だった程度にアクセラレータと従来のコアを融合すること、すなわち、汎用コア中の別々のレジスタとALUのセットだけのためにアクセラレータを「減らす」ことは困難であるので、おそらく別々のコアで残るだろう。結局、アクセラレータは、インコヒーレントキャッシュ、極めて異なるパイプライン設計、GDDR5メモリ、一桁以上多いレジスタとマルチスレッドなどの非類似なアーキテクチャ上のトレードオフに基づいているため、とても速く、高並列で、エネルギー効率的である。それ故、別々のアクセラレータコードを実行することの複雑さが残るだろう。同じダイ上のコアでさえ、メモリ階層の底よりも多くを共有しない傾向があり、CPUとアクセラレータコア間のデータ転送は、速くなる可能性はあるが、ボトルネックもまた残るだろう。

デバイス間のデータ交換の明示的な調整は、エラーの重大な原因とプログラマーに対する多大な負担となっている。短いカーネルのために、実際の計算を表現するよりも、前後にデータを転送するためにより多くのコードを書く必要がよくある。この負担を解消することは、C++ AMPやOpenACCなどの高レ​​ベルのプログラミングアプローチの主な利点の1つである。たとえ低レベルアプローチが、この問題に対処してきても。例えば、合理化された統合メモリアドレッシングは、最新のCUDAとOpenCLのリリースとNVIDIA GPUハードウェアの大幅な改善の一つである。しかし、良好なパフォーマンスを達成するために、OpenACCのような非常に高レベルのアプローチであっても、プログラマによる幾つかの助けが一般的に必要とされている。具体的には、局所性を意識したメモリ割り当てとデータ移行は、しばしば手作業で処理しなければならない。

残念ながら、このような改善が提供するどんな容易さも、部分的な解決策となることが分かるだけかも知れない。将来のマイクロプロセッサが今日の(小さな)スーパーコンピュータと同様であろうという仮定に基づいて、共有(NUMA)メモリシステムが提供される可能性よりも、より多くのコアが含まれるかも知れない。代わりに、各クラスターがおそらく3Dデザインでコア上に積み重ねた独自のメモリを持っている、各ダイ上のコアのクラスターがあるだろうと思っている。クラスターは、MPIと同類のプロトコルを使用してチップ上のネットワークを介して相互に通信する。Intelが将来のXeonチップ内にネットワーク機能が含まれることをちょうど発表したように、これは現実的でないと思わなかったが、それはこの方向への第一歩である。それ故に、将来のチップがレイテンシとスループットが最適化されたコア、NIC、暗号化および圧縮コア、FPGA等から成る、ますます異種混合されたものとなるだろう。

それは、このようなデバイスをどのようにプログラムするかのすべてに重要な問題を提起する。我々は、その答えがどのように今日の複数CPUコア、SIMD拡張命令セット、および計算アクセラレータが使用されているのかと驚くほど類似していると考えている。基本的には、これが行われる3つのレベル、ライブラリとして参照、自動化ツール、そしてセルフプログラミングがある。ライブラリアプローチが、最も単純で、他の誰かによって加速化されたライブラリ内の関数を呼び出すことで機能する。最新の数学ライブラリの多くは、このカテゴリに属する。計算の殆どはライブラリコード内部で行われるため、このアプローチは非常に成功している。これは、幾名かの熟練したライブラリ作成者が多数のアプリケーションのアクセラレーションを有効にすることができる。

自動化ツールのアプローチは、C++ AMPとOpenACCによって取られるアプローチで、コンパイラが力仕事を行う必要がある。このアプローチの成功は、利用可能なソフトウェアツールの品質と洗練度合に依存し、触れたように、しばしばプログラマからの助けを必要とする。それにもかかわらず、ほとんどの開発者は、このアプローチで肯定的な結果を合理的かつ迅速に達成することができ、ライブラリ内の所定の機能に限定されるものではない。これはおそらく、少数の専門家チームがSQLの内部動作をコード化する方法を思わせ、その後の最適化と専門家がコード化したノウハウから多数の「標準」プログラマが恩恵を受けることができる。

最後的に、セルフプログラミングのアプローチは、プログラマにアクセラレータのほぼ全ての側面への完全制御とアクセスを与えるCUDAやOpenCLによって表現される。もし、うまく実装された時には、コードの結果は他の2つのアプローチを凌駕することができる。しかし、これは、急な学習曲線、書く必要がある沢山の特殊コード​​、そしてバグによる沢山の付加的な可能性という犠牲を払う。常にデバッグとプログラミング環境の改善を行うことは、少しだけであるが、これらの問題を軽減する助けとなる。それ故に、このアプローチは前述のライブラリとツールを書いているような熟練プログラマーにとって主に役立つ。

それは使うのにありふれているため、プログラマは可能な限りライブラリアプローチを採用する。しかし、これは適切なライブラリ関数の有効性次第であり、標準的な行列演算(BLAS)のような明確に定義された、成熟した領域の中で提供することは簡単だが、新たな領域もしくは非構造計算のために行うのは難しい。適切なライブラリが存在しないと、プログラマの2番目の選択肢は、ツールが成熟したと仮定して、ツールアプローチになると思われる。ライブラリで利用出来ず、最高の性能も要求せず、コンパイラによってサポートされるどんな計算でも、ツールアプローチを使用してコード化る可能性が高い。残りのケースでは、セルフプログラミングのアプローチが使用されなければならない。OpenCLは、CUDAが導入した成功したアイデアを取り入れ、非独占であり、大規模な範囲のハードウェアをサポートしているので、我々はOpenCLまたはその派生が、MPIが分散メモリプログラミングにおける事実上の標準となっている方法と同様に、この領域を支配し始めたと思っている。

上記で概説したハードウェア機能と進化の調和を得て、将来のプロセッサチップは独自のメモリを搭載した複数のクラスタが含まれているかも知れず、各クラスタは全コアが必ずしも同じ機能を持っている必要の無いコアのセットで構成され、各々のマルチスレッド化された計算コアが多数のプロセッシングエレメント(すなわち、機能ユニットまたはALU)を含み、そして各プロセッシングエレメントはおそらくSIMD演算を実行することができる。実際のチップが上記のすべてを含まない場合でも、それらすべてはキーの類似性、すなわち異なる並列化レベルの階層を共有する。効果的かつシステムのような移植性のあるプログラムのために、我々は「多量-並列処理」技術と呼ぶものを提案する。これは、MPIプログラムが利用可能な計算ノードの数に適応するために典型的かつ明確に書く方法、もしくはOpenMPのコードが利用可能なコア(またはスレッド)の数に暗黙のうちに適応するための方法を一般化することである。

多量並列処理の背後にある主な考え方、およびその名前の理由は、各レベルにおける十二分で、パラメータ化可能な並列処理を提供することである。パラメータ化は、そのレベルでのハードウェア並列性と一致する任意のレベルで並列化を減少させることを可能とする。例えば、共有メモリシステムにおいて、並列化の最高レベルは必要ではなく、ただひとつの「クラスター」に設定されるべきである。同様に、関数ユニットのあるコアでは、SIMD命令を実行できず、SIMD幅を決定するパラメータはひとつに設定されるべきである。この技術は、現在のマルチコアCPU、GPU、MIC、およびその他のデバイスだけでなく、見込みのある将来のアーキテクチャの共通機能を活用することができる。この方法でソフトウェアを書くことは間違いなく難しい一方、多量並列処理は、単一コードベースでコンピューティングデバイスの広い範囲から高性能を引き出すことが可能となる。

我々は、直接N体シミュレーション[参照]でこのアプローチをテストしている。我々は、OpenCLで単一の多量並列処理の実装を書き、4つの非常に異なるアーキテクチャ上でそれを評価した:NVIDIA GeForce Titan GPU、AMD Radeon 7970 GPU、Intel Xeon E5-2690マルチコアCPU、およびInetl Xeon Phi 5110P MIC。54%の非FMA演算のFLOP混合を考えると、多量並列処理コードは、Titan上で理論ピーク性能の75%、Radeon上で95%、CPU上で80.5%、そしてMIC上で80%を達成している。これは単なる一例であるが、結果は非常に有望である。事実、我々は多量並列処理技術がよくなり、現在および将来のアクセラレーテッドシステムのプログラミングのための唯一の移植可能な高性能アプローチでかなりの時間残ることが出来ると信じている。

著者について

20140109-F1-1

Kamil Rockiは、IBM Researchのポスドク研究員である。カリフォルニアのAlmaden研究センターに入社する前、彼は、日本の東京大学で5年間を過ごし、情報科学の博士号の学位を取得し卒業した。その前に、Warsaw工科大学からコンピュータサイエンスの学士号と修士号の学位を取得した。現在の研究は、高性能並列アルゴリズムとハードウェア設計に焦点を当てている。その他の関心には、スーパーコンピューティング、人工知能、コンピュータビジョンとロボティクスが含まれている。彼は、過去8年間、GPGPUプログラミングの分野に従事してきました。

 20140109-F1-2

Martin Burtscherは、テキサス州立大学のコンピュータサイエンス学科の准教授である。彼は、スイス連邦工科大学(ETH) Zurichからコンピュータサイエンスの学士/修士号を与えられ、コロラド大学Boulder校でコンピュータサイエンスの博士号を取得した。Martinの研究の関心は、GPUとマルチコアCPUのためのプログラムの効率的な並列化、自動性能評価と最適化、高速データ圧縮が含まれる。彼は、IEEEとそのコンピュータ団体、そしてACMのシニアメンバーである。Martinは、NVIDIAのGPU Computing Gemsの章を含む75以上の査読済み科学的出版物を共同執筆しており、そしてNVIDIAの学術パートナーシップ賞の受信者であり、CUDA教育センターの主任研究員(PI: Principal Investigator)である。