はじめに
僕は某大学院のアーキテクチャ研究室に所属している学生です(某とはいえどもそもそもアーキテクチャの名前出してる時点で調べたら僕の本名含めて色々出てきます)。マニュアルでは一般のエンジニアに上手く伝わらない点などもあり、自分の理解を深めるとともにQiitaを普段読んでいるみなさんにIMAXというものについて語りたく、このシリーズの連載を始めることにしました。なお、このシリーズの連載に関して、指導教員の許諾等は一切もらっていませんが、別に論文等で公表されていることを自分なりに解釈してあげるのは自由なんで、僕は気にせず上げていきます。でもこのシリーズ記事に関する問い合わせを僕の指導教員にするのはやめてくださいね。あくまでも僕の理解と意見です。
今回は、とりあえずCGRAについて説明していきたいと思います。
背景
最近、ニューラルネットワークやブロックチェーンが世の中で流行るようになり、並列計算に特化したGPUの需要が高まりつつあります。どちらも、並列計算が得意なGPUに向いている最適なアプリで、NVIDAの場合CUDAという便利なライブラリまで使用できます。
しかし、モデルが巨大化していくにつれ、従来のハードウェアだけでは限界を迎えつつあります。GPGPUで巨大モデルを手元で動かすことは到底不可能なことで、半導体プロセスの微細化も今後はあまり期待できません。サーバ・クライアントモデルもネットワークが使用可能な環境に限って有効な手段です。
また、大量の電力消費が許されるデータセンターにおいても、莫大なニューラルネットワークモデルを処理するために専用ハードウェアを導入する必要が出てきました。AlphaGo時代から台頭したTPUというものもそのような専用ハードウェアです。
TPUは、行列積に特化した設計になっています。CPUやGPUのように、プログラミング言語で作成されたプログラムがなんでも動くという設計にはなっていません。多数の演算器を配置し、データをそれぞれの演算器に渡し、最終的に行列積の演算ができる、という仕組みになっています。単なる行列積演算で、同じ半導体プロセス、同じ電力消費でGPUが演算速度で勝てるはずがありません。
しかし、TPUは行列積「しか」できないのがネックになっています。まぁ、行列積が速くなったらだいたいのニューラルネットワークモデルでは問題ないけど、ニューラルネットワークモデル以外の使い道はあまり思いつきません。すべてにおいてGPUの上位互換というわけではありません。
FPGAというものも存在します。FPGAは、論理回路やフリップフロップ等をたくさん配置したチップで、好きな論理回路を書き込むことができます。しかし、構成単位がLUTやFFになってしまうので、物理的な限界によってクロックの向上等が難しいところがあります。僕自身、自作CPUをやったことがあってFPGAに触れたこともあるし、FPGA自体は好きですが、物理的特性が専用チップよりはあまりよろしくありません(当たり前ですが)。
専用チップは、アプリケーションにおける演算の種類が大きく変わってしまうと使えなくなる場合がほとんどです。手軽に最先端プロセスのチップを量産できるわけでもないので、製造に多大な資金が必要となります。
このような問題に打ちあったている現状を打破するため、CGRAというものが浮上しつつあります。
CGRAとは?
CGRAは、粗粒度再構成可能アーキテクチャ(Coarse-Grained Reconfigurable Architecture)の略です。どういった概念なのかあまりピンとこないかもしれません。
FPGAは論理ゲートレベル(正確にはLUT単位)で再構成を行なって擬似的に回路を構成します。しかし、これは物理的特性があまりよろしくない、という話を上でしました。その論理ゲート単位になっている再構成レベルを、演算器単位、もしくはそれ以上に粗くしたのがCGRAです。ニューラルネットワークの演算において、RTLレベルまで考慮すべき要素はありません。というか、ほとんどのソフトウェア的処理もそのはずです。想定されるアプリケーションで要求される演算レベルで分割し、再構成可能にするのが特化したチップを作るにあたって賢い道筋のはずです。
CGRA自体、特定のアーキテクチャではなく、データベースの世界に例えるとNoSQLのような広範囲な概念を指すようなものなので、構造もプログラミングの仕方も向いているアプリケーションも様々です。そして、すべてのプログラムが動くわけではないので、Geekbenchのような共通化したベンチマークで優劣の比較もできませんし、想定されるアプリケーションに最適化されたCGRAを採用するか自分で設計すべきです。
CPUですら、「すべてのタスクに関していい性能を叩き出す」コアは存在しません。ベンチマークソフトウェアは、なるべく公正な比較のために様々な演算を試しますが、それでもベンチマークごとに優劣が変わるのもその理由です。
リニアアレイ型CGRAとは?
CGRAにも様々な形があります。演算器を一次元にも、二次元にも、三次元にも広げることは可能です。どのように繋ごうが、CGRAという範疇には属します。リニアアレイ型CGRAは、その言葉から推測できるように、演算器が線型に繋がっているようなものを指します。このシリーズで紹介するIMAXも、リニアアレイ型CGRAです。
リニアアレイ型の利点は、二次元上のユニットの連結を考える必要がないためFPGAのような論理合成に多大な時間を要するようなことが起きない点です。IMAXの場合、CPUのようなユニットが直線状に繋がっています。横とのつながりを考える必要がなく、データフローに集中できる点、リニアアレイ型CGRAの強みと言えます。
「直線状であれば二次元上に広げるより空間効率悪いのでは?」と思うかもしれません。しかし、その直線状のものを横に大量に配置すれば並列性能を上げられるので、大きな問題にはなりません。あと、IMAXの場合、一応一ユニットあたり四つの演算とメモリロードを設定できるようになっているので、一度に複数のデータをロード、計算すること自体、問題ありません。
もちろん横に繋げることのメリットはアプリケーションによってはあるかもしれません。しかし、少しでも規模が大きくなると「コンパイルに多大な時間がかかる」という問題が生じてしまいます。テストが重要なソフトウェア開発フローにおいてかなりネックになってしまいます。空間的複雑性を減らし、またそれが一般には問題ないという思想の元、リニアアレイ型CGRAは作られました。
IMAXの紹介
構造
IMAXは、前述の通りCPUのようなユニットを直線状に連結しているような構造をしています。各ユニットには、演算器とローカルメモリ、そしてレジスタが入っています。各ユニットの下にあるレジスタは、次のユニットの演算時に使用できます。これらのユニットに、様々な命令をセットし、自分がしたい演算を実装していきます。
上の図のものが基本ユニットです。IMAXでは、これが横に四つ、縦に任意の数が配置されています(実測に使っているものは32か64個)。中にはLMMと表記されているローカルメモリが存在し、ここにデータをロードし、下のレジスタにロードします。また、上のレジスタからデータを受け取り、演算器で演算を行い、その値をレジスタに保存することも可能です。
一番左にある紫色で囲まれている三段重ねの演算器が実際の数値の計算のためのもので、三段重ねのユニットを全部使うと浮動小数点演算も可能で、それぞれを使うと整数の四則演算(割り算を除く)、論理演算、シフト演算をそれぞれ使うこともできます。
右の茶色で囲まれている演算器はアドレス計算のためのもので、LMMへのロードやストアのアドレスの定義に使用します。
連結するとこのような形になります。マニュアルの実装例のマッピング図ですが、このように命令が割り当てられ、指定されたメインメモリ番地からローカルメモリへロードし、また演算が終わったらメインメモリに戻す構造になっています。
もちろん、メモリの書き戻しを毎回やるとあまりCGRAの良さを活かせないので、ローカルメモリにロードしたデータをできる限り使い回し、演算を行うようにプログラミングを行う必要はあります。
性能
マニュアルにある性能比較ですが、
各種演算において良い電力効率を達成していることがわかります。EDPが電力効率を表す指標で、低いと良いとされます。FPGA上の実装での計測なので、実測値はGPUに比べると遅くなてしまいますが、それでも一昔前のハイエンドGPUと戦えるレベルであることは間違いありません。
終わりに
今回は、リニアアレイ型CGRAであるIMAXの存在について解説しました。次からは、実際のプログラミングの仕方などを解説していきます。じゃまた。
次回の記事
AIアクセラレータ・IMAXの紹介 ~ (2) IMAXのツールチェーン及び環境構築方法