※本記事はInterface誌2022年10月号に掲載されたものの原稿版になります

スーパーコンピュータの技術が貴方の掌に

 第4回目では、ベクトルプロセッサに焦点を合わせて話したいと思います。近年、オープンな汎用プロセッサISA(Instruction Set Architecture)としてRISC-Vが注目浴びる様になってきました(文献(1))。RISC-Vの特長の一つとして、RVV(RISC-V Vector extension)と呼ばれる可変長ベクトル命令が定義されている事が挙げられます。可変長ベクトル命令を有するプロセッサはベクトルプロセッサと呼ばれ、1970年代後半~2000年代前半までスーパーコンピュータと言えばベクトルプロセッサの事を指していました。当時のベクトルプロセッサは1CPUでも人の背丈ほどに大きく、消費電力もけた違いでした。初期のベクトルプロセッサの仕様をみると、1CPUで高さ1.9m×幅2.6m、消費電力115KWとあります(文献(5))。しかし、現在では半導体プロセスの微細化と省電力化により100mm^2以下というSoC(System on Chip)に収まるサイズかつ消費電力10W程度で実現可能となってきました。更にRISC-V ISAの普及により、ベクトルプロセッサは組込み用途でも拡大の兆しを見せています(文献(2))。

SIMD命令と可変長ベクトル命令の違い

 現在用いられる高性能プロセッサのほとんどはデータレベルでの並列性を活かすためにSIMD(Single Instruction Multiple Data)命令と呼ばれる命令セットを持ちます。例えばIntel X86_64のAVX、ARM AArch64のNEONが代表的なSIMD命令セットです。一方で、RISC-VではRVVと呼ばれる可変長ベクトル命令が定義されています。これらは一つの命令で複数のデータを一括処理するという性質が似ていますが、幾つか異なる性質も持ち合わせています。 

 図1, 2はSIMD命令と可変長ベクトル命令の違いを示しています。これら両者の違いは各々が出てきた背景の違いに起因するものです。 

 IMD命令は主に1クロック当たりの見かけ上の演算性能を向上させる目的で出てきたもので、「1クロック毎に行える演算器の幅」=「レジスタ長」となります。プロセッサがキャッシュメモリを有する事を前提としており、SIMD命令自体にはメモリ遅延の隠蔽する機能はありません。レジスタ長が長ければ長いほど見かけ上の演算性能は高くなりますが、単純に長くしてしまうとメモリ周りの制約に縛られて高い実効効率を維持するのが難しくなります。 

 可変長ベクトル命令はプロセッサが有する演算器の稼働率を100%に近付ける目的で出てきたもので、「1クロック毎に行える演算器の幅」<<「レジスタ長」となります。この長いレジスタの事をベクトルレジスタと呼びます。ベクトルレジスタの長さは命令のチェイニング(例えば、演算器が複数サイクルに渡って稼働する裏でレジスタ-メモリ間の読出し・書出しを同時に実行する事)を意図しての事です。チェイニングはメモリ遅延を隠蔽し、プロセッサの実効演算効率を100%に近付けるために絶大な威力を発揮します(文献(3))。

 ベクトルレジスタ(すなわちベクトルプロセッサ)がキャッシュメモリと本質的に異なる点は設計時に想定するメモリアクセスのパターンにあります。キャッシュメモリはメモリアドレスに対する連続アクセスを想定してキャッシュラインと呼ばれるまとまった単位でのアクセスに最適化されています。ベクトルプロセッサでは完全にランダムなアドレスに対して読み書きする場合でも高い実効性能を出せる様にギャザー・スキャッタと呼ばれるランダムメモリアクセスをサポートする機能を有します。 


図1:SIMD命令の例 

 図1は長さ4のSIMD命令を示しています。SIMD命令では予め決められた長さのレジスタ(この例では32ビット/word×4word=128ビットに対して演算を行います。レジスタ上の全ての要素の演算は同時に行われます。 

図2:可変長ベクトル命令の例  

 図2は可変長ベクトル命令を示しています。可変長ベクトル命令ではベクトルレジスタの長さはベクトル長レジスタと呼ばれる特別なレジスタに設定され、制御されます。クロック当たり何要素の加算が行われるかはプロセッサのマイクロアーキテクチャによって決まっており、一般には複数サイクルに渡って一つの演算命令が処理されます。

具体的なプログラム事例:ループのベクトル化 

 SIMD命令も可変長ベクトル命令も、複数のデータを一括処理するという特性から主にループ処理に対して適用されます。ループ処理をSIMD命令・可変長ベクトル命令が適用可能な形へ変換する事をベクトル化と呼びます。ベクトル化はコンパイラが自動的に行ってくれる場合もあります(文献(3,4))が、組込み関数やベクトルデータ型を用いてユーザが直接プログラムを書き換える事が一般的です。図3, 4にC言語によるループのベクトル化の例を示します。図中、左側が元のプログラムを示し、右側がベクトル化されたプログラムです。SIMDデータ型及びベクトルデータ型には代入・四則演算子が使える事を想定しています。一見すると、元のプログラムに比べてベクトル化されたプログラムは行数が増えて複雑になっている様に見えますが、ループ本体の実行回数が減っている事に注意してください。SIMD命令/可変長ベクトル命令共にベクトル化されたプログラムの方が高速に動作します。 

図3:SIMD命令によるループのベクトル化の例 

 図3はSIMD命令によるベクトル化を示していますSIMD命令では命令によってレジスタの長さが固定されてしまうため、処理するループの長さがレジスタ長で割り切れない場合、余りの部分に関してはスカラ演算命令(1要素毎の演算命令)を用いて処理します。一般的に、スカラ演算命令は一命令で一要素しか演算ができないため、SIMD演算命令に比べて低い演算効率となります。 


図4:可変長ベクトル命令によるループのベクトル化の例 

 図4は可変長ベクトル命によるベクトル化を示しています。可変長ベクトル命令では最大ベクトル長(MAX_VL、マイクロアーキテクチャで規定されるで典型的には64~256)以下あれば任意の長さのベクトル長を設定できます。通常はベクトル長レジスタを最大ベクトル長に設定してループの処理を行います。ループの長さがベクトル長で割り切れない余りの部分に関してベクトル長レジスタの値を調整した上で同じ命令を用いて一括処理できるためプログラムが簡潔となり、高い演算効率を維持する事ができます。 

ベクトルプロセッサの歴史を振り返って 

ここではベクトルプロセッサの歴史を簡単に振り返ってみたいと思います。ページ数制約の都合上全てを書き切ることができないので、詳しい内容は各参考文献を参照してください。

ベクトルプロセッサの歴史は1976年にCRI(Cray Research Inc.)より発表されたCray-1まで遡ります(文献(5))。このプロセッサは80MHzで動作し、最大演算性能160MFLOPS(Mega FLoating-Points per Second/一秒間に実行できる演算回数)、メモリ容量8MBでした。図5,6に当時のメモリとプロセッサボードの写真を示します。大きさが実感できる様に左下には500円玉を置いてあります。どちらも銅板でできた巨大な5層基盤ですが、当時はこれらのボード数百枚を、人の背丈ほどもある筐体のバックボーンを介して接続する事で1台のベクトルプロセッサを構成していました。 

80年代に入ると日本のメーカーもベクトルプロセッサの市場に参入しました。日立は汎用機の拡張演算機構として動作するHITAC Sシリーズ、富士通は分散システムを指向したFACOM VP/VPPシリーズ、NECは共有メモリ型並列プロセッサを指向したSXシリーズという様に各社独自の特色あるベクトルプロセッサを製作し、CRIを凌駕する高性能な製品を次々と投入して行きました(文献(6))。ちなみに、筆者が90年代後半に初めて触れたベクトルプロセッサは東大の大型計算機センター(現在の情報基盤センター)にあった日立S-3800/480でした。これは当時の世界最高速となる8GFLOPSのベクトルプロセッサを4台搭載したシステムです。手元のワークステーションで動作していたFORTRANプログラムを移植すると数百倍の演算速度で動作しました。あまりの速さに計算が正しく行われていないのではないかと何度も確認したのを覚えています。 

2000年代に入るとSIMD命令を有するマイクロプロセッサの急激な高性能化と低価格化によりベクトルプロセッサは徐々にマーケットシェアを落として行き、日立、富士通が新規開発から撤退する一方、JAMSTEC(海洋開発研究機構)の初代地球シミュレータプロジェクトはベクトルプロセッサを採用する事で大きな成功を収めました(文献(7))。同プロジェクトの特筆すべき成果の一つとして、ベクトルプロセッサのマイクロプロセッサ化が挙げられます。時を同じくして米国ではCRIの後継のCray Inc.が発足し、2002年には筆者も深く関係したX1というMCM(Multi-Chip Module)マイクロプロセッサ構成のベクトルプロセッサを用いた超並列型スーパーコンピュータが製品化されました。MCMはチップレットとも呼ばれ、当時はPOWER5というIBMのハイエンドプロセッサに用いられていました。現在ではAMDのプロセッサRyzenにも用いられて注目される技術です。X1は衰退期を迎えていたベクトルプロセッサの復権を果たすという目的を達成し、ある程度の成功を収めました。同社は2005年にX1をデュアルコア化したX1Eを発表し、2007年にはインターコネクトモジュールをプロセッサに取り込みSoC構成とした後継機種X2の販売を最後にベクトルプロセッサから撤退しました。そして2020年にはHPE(Hewlett Packard Enterprise Inc.)と合併して今日に至ります。

ここ15年ほどの間はベクトルプロセッサにとってはあまり良い時期ではありませんでした。GPGPU(General Purpose Graphics Processing Unit)をはじめとする各種アクセラレータの普及もベクトルプロセッサの衰退に追い打ちをかけたと言えます。しかし、今日においても流体力学や構造計算など大規模なデータを大域的に扱うアプリケーション分野においてはベクトルプロセッサの優位性は揺らいでいません。その技術は今なお日本で受け継がれて今日に至っています(文献(2, 8)) 

  写真1:Cray-1のメモリボード

写真2:XMP(Cray-1の後継機)プロセッサボード 

将来への展望とまとめ 

かつて、ベクトルプロセッサは科学技術計算のために限られたユーザが用いるものでした。一度は衰退の道を辿りましたが、ムーアの法則が成り立たなくなった現在、マルチコア化やSIMD命令の次の並列化技術として再び脚光を浴びています。更に、RISC-V ISAの普及に伴ってRVV命令を有する組込みプロセッサが登場し、今まさに自動運転車やロボティックスなど様々な産業用途で使われようとしています。 

ベクトルプロセッサはランダムメモリアクセスに強いその特性から、巨大な配列データを大域的にインデックス参照で引いてくる場合(スーパーコンピュータでは主に疎行列と呼ばれるデータの格納に用いられ、CPUもGPGPUも苦手とするタイプの処理です)などキャッシュメモリだけでは隠蔽しづらいタイプのメモリ遅延を比較的容易に隠蔽できる事が知られています。歴史的な経緯から科学技術計算・数値計算分野の用途では十分に研究されていますが、使い方次第ではまだまだ大きな可能性を秘めています。これから先、産業用途に用いられる事でどの様な進展を見せてくれるのか、非常に楽しみです。 

 ****
にしむら せいじ
****

この記事の関連製品

ベクトルプロセッサを搭載したAkaria製品について
制御MCU向けアクセラレータ Akaria DR1000C
RV64GCV対応RISC-Vコア Akaria NS72A

 

本記事に登場する用語の解説

用語  意味 
FLOPS(FLoating point Operations Per Second)  プロセッサが1秒間に演算できる浮動小数点演算回数。1FLOPSは1秒間に1回の加算ないし乗算ができる事を意味し、1MFLOPSは100万回の演算性能、1GFLOPSは10憶回の演算性能を各々意味します。 
GPGPU(General Purpose Graphics Processing Unit)  3Dグラフィックスだけでなく汎用処理もプログラミングできるGPUの事。プログラミングには一般的にSYCL、OpenCLやCUDAという専用言語が用いられます。 
ISA(Instruction Set Architecture)  プロセッサが解釈可能な命令集合の定義。 
MCM(Multi-Chip Module)  複数種類のチップを結合して構成する半導体の技術。チップレットとも呼ばれます。 
RISC-V  UCB(カリフォルニア大学バークレー校)に起源を持つオープンかつフリーなISA規格。 
SIMD(Single Instruction Multiple Data)  1命令で複数のデータ(=演算子)を処理する事。画像処理や行列・ベクトル演算は同じ演算操作を複数のデータに対して作用するため、SIMD処理に適しています。 
SoC(System On Chip)  プロセッサ本体だけでなく、アクセラレータやメモリコントローラ、ペリフェラル等も一緒に半導体に集積する事。 
可変長ベクトル命令  処理するデータの長さ(=ベクトル長)を設定できるSIMD処理向けの命令。 
ギャザー・スキャッタ  ギャザーとはメモリ上のランダムなアドレスに置かれたデータをベクトルレジスタにロードする事。逆にスキャッタとはベクトルレジスタ上のデータをメモリ上のランダムなアドレスにストアする事を指します。ベクトルプロセッサではギャザー・スキャッタを行う専用命令が存在し、それをサポートするハードウエアの機構を有します。 
キャッシュライン  メモリとキャッシュの間でやりとりするデータの単位。 
チェイニング  例えば「ロード⇒加算⇒積算」という様に、先行命令結果をすぐに後続命令で用いる可変長ベクトル命令列を複数結合し要素毎にパイプライン処理する事及びそれをサポートするハードウエア機構を指します。チェイニングによって先行発行の命令が完了する前に後続の命令をスタートさせ、複数の命令を同時実行する事が可能となります。 
ベクトルプロセッサ  可変長ベクトル命令とベクトルレジスタを有するプロセッサの事。 
ベクトルレジスタ  可変長ベクトル命令を処理するために複数語のデータを載せる事のできるレジスタ。 
ベクトル化  SIMD命令ないし可変長ベクトル命令が適用可能な様にプログラムを書換える事。主にループ処理が対象となります。 

 

参考文献 

  1. デビッドパターソン, アンドリューウォーターマン著, 成田光彰訳, “RISC-V原典”, 日経BP, 2018年. 
  2. NSITEXE Inc. DR1000C
    https://www.nsitexe.com/ip-solutions/data-flow-processor/dr1000c/ 
  3. シドニーファーンバック著, 長島重夫訳, “スーパーコンピュータ 超高速計算のためのハードウエアとソフトウエアのすべて”, パーソナルメディア, 1988. 
  4. Michael Wolfe, “Optimizing Supercompilers for Supercomputers”, MIT press, 1989. 
  5. Cray Research Inc., “Cray-1 Hardware Reference Manual”, Cray Research Inc., 1976.
    https://history-computer.com/Library/Cray-1_Reference%20Manual.pdf 
  6. 情報処理学会 バーチャルミュージアム
    https://museum.ipsj.or.jp/computer/super/index.html 
  7. 国立研究開発法人海洋開発機構 地球シミュレータ開発史
    https://www.jamstec.go.jp/es/jp/publication/pdf/Development_ES.pdf 
  8. NEC, SX-Aurora TSUBASA
    https://jpn.nec.com/hpc/sxauroratsubasa/index.html