AppleがRISC-Vのプログラマーを募集しているという。MacのプロセッサをIntel製から自社製のArmに移行し始めたばかりのAppleが、早くも「RISC-Vに移行?」というわけではないようだ。それでも最近、RISC-Vに注目が集まっているのは間違いないようだ。で、このRISC-Vってどんなプロセッサなの?
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
既に「RISC-V(リスク・ファイブ)」については、何度か書かせていただいている。最近もAppleがRISC-Vのエンジニアを募集というニュースが流れて盛り上がりつつあるらしい(Appleの求人情報「RISC-V High Performance Programmer」[英語])。今回はビジネス的政治的な話は抜きにして、純粋にRISC-Vのどの辺が素晴らしいのか(あるいはArmやx86と比べてどう変わっているのか)を考えてみたい。
まずRISC-Vというのは、古典的な意味でのコンピュータアーキテクチャ「ISA(命令セットアーキテクチャ)」の規格だということを押さえておいていただきたい。現代的にはプロセッサ内部の構造まで含めて「(マイクロ)アーキテクチャ」などと呼称する場合があるが、古典的定義ではどういう回路に実装するか(インプリメンテーション)は、全く含んでいない。
昔、ミニコンの星だったDEC(Digital Equipment Corporation)のVAXの教科書に「アーキテクチャというのは鍵盤」「インプリメンテーションというのはグランドピアノかアップライトピアノかなどの構造」という例えが掲載されていた記憶がある。ここでピアニストに当たるがシステムレベルのプログラマーだ。
プログラマーから見えるアセンブラの記法、その機械語へのエンコード、その命令を動作させたときのレジスタやメモリの変化の記述、特権モードや仮想記憶、そしてレジスタやスタックの使い方に当たるABI(Application Binary Interface:アプリケーションプログラムとOS/ライブラリ間のバイナリレベルのインタフェース)などが、RISC-Vが決めている範囲だ。
全て文書として記述されるものであって、そのサマリーはたった表裏2面のリファレンスカードにまとめられている。ここで一言指摘すればシンプルなものは安く作れる。
さて、このようなアーキテクチャはArmにせよ、x86にせよ存在する。ただし、RISC-Vは、これら既存のプロセッサとその発想からして違うのだとしている。「モジュラー」対「インクリメンタル」だ。
若い人に受ける例えかどうかは分からないが、既存のプロセッサは、温泉旅館の建て増し方式で拡張をしてきている。本館を建て、別館を作り、新館を作りという具合に次々新築していく。古い建物はリフォームや増築もする。そして、その間を回廊でつなぐのだ。巨大だが複雑な迷路が出来上がる。時には古い建物を取り壊して更地にして立て直すこともある。その場その場の需要に応じて計画しているので、局所的には合理的でも全体を通じての整合性は低い。
これに対して、RISC-Vはモジュラーだというのだ。その基礎には「RV32I」という「凍結」された命令セット(プログラマーが常に使用できることを当てにできる)が据えられている。この部分は、1個数十円の組み込みRISC-VマイコンからHPC(スーパーコンピュータ、採用されればだが)まで共通だ。
その上に、乗除算、浮動小数点、アトミック、ベクトル、特権などの各種の拡張命令セットが定義されている。実際にチップをインプリする場合には、それら拡張を適宜組み合わせて使用する、というスタイルだ。ミニマムなものを安く作ってもよし、マキシマムなものを指向してもよしだ。そして、全ての各拡張は相互に矛盾のないように計画されている。
拡張の一例を挙げよう。16ビット長の命令はプログラムコードの縮小に効果がある。メモリに限りのある組み込みでは欲しい機能だ。Armは、もともと32ビット固定長だったが、組み込み向けに「Thumb」という16ビット長の命令セットを追加した。そしてCortex-Mシリーズなどの組み込みでは「Thumb-2」と呼ぶ32ビット/16ビット混在の命令セット(名前が紛らわしいがThumbの上位互換ではない)を採用している。そして、それらの命令セットを全て実装したプロセッサがあったとしても、1個のコンテキストにそれら命令を混在させることはできない。切り替えが必要だ。
一方、RISC-Vを見てみよう。基本のRISC-Vは32ビット固定長命令で32ビットレジスタ32本が使える。そして16ビット長の命令(32ビットレジスタ16本が使える)も拡張として定義されている。
ただし、その機械語命令のエンコードは16ビットと32ビットが混在しても大丈夫なようにアサインされている。そして、全ての16ビット長の命令動作は、32ビット長の命令でも指定可能となっているのだ。16ビット長の命令はレジスタ16個しか操作できないが、意味的には完全サブセットである。
そして、16ビット長命令に割り当てられているのは、32ビット長命令においても頻繁に使うと予想されるレジスタに対する操作なのだ。ABI的にも両立するようになっている。つまり、16ビット長の「拡張」を持たない32ビット固定長のプロセッサ上で動作可能なプログラムソースを、16ビット長対応の「拡張」を持ったターゲット向けに再アセンブルすれば、オブジェクトコードサイズは減少する。高使用頻度の命令を中心に「短縮化」が定義されているから効果は大きいはずだ。
このような配慮のため、RISC-Vの機械語命令のエンコードや、ABIのレジスタの割り当ては、既存のプロセッサのそれを見慣れていると、とびとびの妙な割り付け方に見える。
しかし、その妙な割り付けには、相互に矛盾なく拡張できるための配慮、それから実装時にハードウェアが小さくなるであろう配慮が行き届いている。RISC-Vは、ハードウェア実装を縛ることはないが、小さく速いハードウェアで実装可能であるように深く検討された上で決められているのだ。
そしてArmから20年後発のRISC-Vは、過去のプロセッサの失敗事例も学んでいる。導入時にはもてはやされたけれど、後で問題となったような定義は排除されている。例えば、「遅延分岐命令」「条件付き実行」「スタックフレーム生成命令」などは、RISC-Vには存在しない。
だから命令セットを見るとプレーンでミニマム、特徴がないように見える。しかし、よく見ると細かいところに配慮が行き届き、シンプルな命令で効率を上げられる命令セットなのである。
RISC-Vが、過去のプロセッサの屋下に屋を架すみたいな場当たり的な拡張への反省のもと、最初から拡張性を考えて、矛盾が生じないように、かつ実装の足を引っ張るような妙な特徴を入れないようにしていることは分かっていただけただろう。
だから、RISC-Vインターナショナル(このアーキテクチャの規格を定めている団体)は、今でも拡張の作業を続けているのだが、安易な拡張をポンポン出してくることはないと思う。1社で勝手に決めることはなく、メンバー各組織のオープンな議論で決める、そして基本の考え方に沿ったものかどうかの吟味が常になされるようだ。
そんな拡張の中で、今後の上位機種展開において注目されると思われるのがベクトル拡張だ。RISC-Vの「V」は、「ベクトル」の「V」でもあるといわれている部分である。これは、Armやx86のSIMD命令に対するアンチテーゼともいえる。
アセンブラでSIMD命令を書いたことがあるだろうか。SIMD命令自体は一度に多くの要素を処理できる力持ちなのだが、SIMDに持ち込むまでの準備や何やらがとても大変だ。SIMD命令の幅からはみ出た端っこの部分などの処理を考えていると、気がおかしくなってくる。ましてやスパースな行列(疎行列:成分のほとんどが「0」である行列)など止めてもらいたい(現実問題はこれが多い)。
RISC-Vは、この問題をベクトル命令中心で解決する。ベクトルの長さやら何やらをベクトルレジスタごとに定義できるのだ。この仕組みにより、SIMDで悩んでいたSIMDの前後のロード/ストアのテクニックや、データのセットアップなどの諸問題は引っ込んでしまう。
ここで気を付けなければならないのは、RISC-Vは、「ベクトル演算器を実装せよ」とも「4096バイト長のベクトルレジスタを実装せよ」ともいっていないことだ。命令の定義としてベクトルなだけであって、実際の内部の演算器は、4並列や8並列のSIMD式のものを必要なだけループで回して処理してもよい。実際のレジスタの幅は、もっと狭くてもいいのだ。それどころかプアなハードウェアなら1個1個処理しても構わない。実装は縛らないのだ。
このベクトル化の効用は、IntelのSIMD命令の歴史を反面教師として見ると、浮き彫りになる。最初、MMXという名で登場したIntelのSIMDは、浮動小数点レジスタに間借りしていた。それでは浮動小数点演算と両立しないし、幅も狭いしとなって、専用のレジスタファイルを備えるようになった。さらに、別なSIMD命令セットを追加し、その後レジスタの幅など増やしたり、増設したりする度に新規の命令を追加してきている。
つまり、新しいSIMDハードウェアの能力を活用したければ、新たなSIMD命令で書き直す必要があるということだ。今では何個命令があるのか、筆者には分からない。手元にあるIntelの命令セットマニュアル(かなり古いものだ)ですら何千ページもある。多分、普通の人は読み切れない。
それがベクトル化命令によってシンプルになる。実際の演算器幅やレジスタの幅などの実装から命令を切り離すことができるのだ。
また、32ビットのRISC-Vだけでなく、64ビットのRISC-Vも、もちろん定義されている。Armもx86(x64)も、今日主流は64ビットの実装なのだから当然である。なお、RISC-Vの場合、128ビットの規格も一応あるということだ。32ビットも64ビットも基本の命令の動作もエンコードも同じ、レジスタ幅が単純に32ビットから64ビットになるだけだ。64ビットにおいては32ビットでなかったワード幅指定のメモリアクセスなどが必要になるので、多少命令が追加されるが基本は同じ。x86のように1本の実体レジスタに短い幅の2本のレジスタを割り当てたりするようなことはない。
バイト/ハーフワード/ワードといったデータの幅は、メモリ上にあるときのみ意味を持つ。レジスタ上ではどのデータも常にレジスタの全幅を占有する(短いデータのロード時はいつも符号拡張されている。命令には符号あり、符号なしがあるので演算上は問題ない)という単純化のおかげでもある。
拡張性についてRISC-Vはかなり配慮していて、有限なオペコード空間を使いきらないようなエンコードになっている。まだまだ余裕があるのだ。シンプルな命令セットなので、もともと命令数が少ない上、ビット幅の広い即値データフィールドなどを排除する工夫のおかげでさらなる命令拡張が検討できる。
また、アドレッシングモードなど実際は1個しかないが、ゼロレジスタを活用することで実質的にモードを増やしているなど、シンプル化の工夫は多い。それら全てがオペコード空間を節約するだけでなく、実装を軽く(コストを安く)し、実行を速くする工夫につながっている。
RISC-Vのいいことばかりを並べてしまったが、ちょいと本稿に懸念がある。書き連ねてきた特長の数々(コストの安さを除く)と、実際に向き合うことになる人の数である。プロセッサのハードウェア(実装)を設計する人、これは当然だ。コンパイラ、アセンブラなどのツールチェーン関係のプログラマー、OSやディープなファームウェアなどのプログラマー、ザックリいって普段からアセンブラやバイナリオブジェクトに親しんでいる層の人々のみじゃないだろうか。組み込みまで入れると意外とその人数は多いような気がするが、C言語レベルでアプリケーション(多分、今ではC言語すらそれほど多くないと想像する)を書いている人よりも一桁、二桁少ない気がする。
そういうディープな層にはRISC-Vのよさがアピールできるだろう(多分とっくに知っているだろう)が、アセンブラなんか意識したことのない人に分かってもらえるのだろうか。結局、Appleが使いそうだからなど、技術以外の理由が必要そうだが……。
日本では数少ないx86プロセッサのアーキテクト。某米国半導体メーカーで8bitと16bitの、日本のベンチャー企業でx86互換プロセッサの設計に従事する。その後、出版社の半導体事業部などを経て、現在は某半導体メーカーでヘテロジニアス マルチコアプロセッサを中心とした開発を行っている。
Copyright© Digital Advantage Corp. All Rights Reserved.