Cell/B.E.

ネットワークレイテンシ縮めるにはどうすればいいか考えてたときにひょっとしたら「CBEならできんじゃね?」とか思って、つまり、NICから直接SPEのLSに入れて、SPEからNICレジスタ叩けば、DRAMのレイテンシも存在しないTCP/IPアプリケーションが作れるのではないかと思ったんですよね。

まあ、実験環境ないのでそう思った以上のことは無いけど…

そのついでに、どのぐらいCBEがよく考えられていたか書いてもいいかなと思ったので書いておく。

(個人的に、Cellという表記/呼びかたはなんかあまり好きではなくて、Cell/B.E.もしくは、CBEと呼ぶので、以下、CBEはそういう意味で読んでほしい)

はじめに

CBEがあんまり普及しなかったとか、半導体業界の背景とか色々あって、多分新規アーキテクチャで世界制覇目指すとかやるのはCBEが最後になる可能性があるし(狭い部分では新規アーキテクチャとかもあるだろうけど)、まあ、こんなのもあったなぁ、と語るにはいいネタだと思う。


CBEは、GPUとかのアクセラレータみたいなのをやろうとしたんでしょ?的な文脈で語られることが多いけど、そうではない。


CBEは、もっと、色々な点で、深読みしすぎてる感があって、つまり、「命令セットきれー」とか、「シンプルなコアで並列化で性能グングン」とかそういうなんかよくわからんのではなくて、I/O、メモリ、リアルタイム、という点で、よく考えられており、本気で、リアルタイム組み込みからHPCまで広くカバーしようという心意気が感じられて素晴らしいので、CPUアーキテクチャ妄想とかする時は、最低限、CBEが目指したものぐらいは踏まえておくべきだと思っているので、CBEがどれだけ素晴らしいかについて書いておく。


CBEA

まず、手元に用意してほしいのが、Cell Broadband Engine(TM) アーキテクチャ(以下CBEA)という資料なのだが、
http://cell.scei.co.jp/pdf/CBE_Architecture_v102_j.pdf
これ何かというと、まあ、何の役にも立たないドキュメントで、なぜこれを日本語化した、という評価がされるぐらい、まあ、ほんとに何が書いてあるかよくわからないドキュメントなのだけど、今日のテーマは、CBEがどれだけ深読みしてつくられたか、という点なので、まさに、これを読むというテーマなんですよね。


つまり、まず、そもそも、最初のCPU(といっても、全部で2種類しかないけど)を作る時点から、将来に備えて、実装とアーキテクチャを分離しておこうという発想が他のCPUとは違う点を見せてくれますね。(多分PowerPCを作ってるIBMの文化だと思うが)

例えば、実装とアーキテクチャが分離してないx86だと、メモリオーダリングが遠い将来においても保証されてるかどうかは誰にもわからないとか大変困ること多いですよね。その点、CBEAに準拠したと書いてあるプロセッサ(といっても全部で2種類しかないけど)なら、遠い将来においても、メモリオーダリングどこまで保証されるかがわかるようになっていて、大変助かりますね。

MMU

まず、「15.3 MFC ストレージ・デスクリプション・レジスタMFC_SDR)」。

今はCUDA/OpenCLが普及してしまったので、アクセラレータ用にメモリを確保するのが当たり前になってしまったけど、CBEの頃は、mallocしたポインタがそのまま(16byteアライン必要だけど)SPEで使えた。

これを支えているのが、このMFC_SDRに関する記述で…といっても、ひとこと「PowerPCストレージ・デスクリプション・レジスタ(SDR1)と同ーの機能を提供します」と書いてあるだけなのだけど、つまり、ページテーブルの構造が、PowerPC互換になっている。
これによって、LinuxとかのOSで作ったページテーブルが、そのままMFCから使えるようになっていて、malloc で確保したメモリアドレスが、SPEから使える、というわけである。

AMD/ARMがやっている、HSAのSTANDARD(http://hsafoundation.com/standards/) のところ開いてもらうと、一個、ぽろっとIOMMUの仕様がころがってるのだけど、超おおざっぱにいうと(いやかなり違うけど)、これの内容が、このMFC_SDRと対応するといってもいい。
つまり、これからはHSAだプログラミングが簡単だウォーとかいうのは、既にCBEが7年前に通った道ということである。(まあ、PCIe超えて何かやるともうちょっと面倒というのはあるけど)

リアルタイム性

SPEは、LSがあるので、リアルタイム処理に向いてる、ぐらいは皆知ってると思うが、残念ながら、その程度の理解ではCBEマスターへの道はまだまだ先は長いといってもいい。

真のCBEマスターになるには、RMT/RAGを理解する必要がある。まあ、僕も調べたことないので知らないが。CBEマスターへの道はまだまだ長い。


リアルタイム性とか考えると、「本当にキャッシュ無くなるだけでいいのか?TLBは?SLBは?バスが混雑したらどうする?」とか、考えるのは、当然の結果だと言っていい。普通のCPUを使っている人は、結局そこらへんが心配で、usecオーダーを保証できないだろう。でも、CBEなら……大丈夫!


まず、「19. キャッシュ置換管理機構」を開いてほしいのだが、この部分をよく読むと、多分キャッシュの置換について書いてあるのだと思…う…?ごめん今初めて見たが、よくわからんわ。まあ、多分そんな感じのことが書いてある。これでキャッシュの心配はしないでいい。


次に、「20. リソース配分管理」を開いてほしいのだが……えーと……ごめん今初めて見たが、何も書いてなかったわ。「詳細については、特定のインプリメンテーションに関するドキュメントを参照してください。」と、書いてあるが、CBEAのインプリメンテーションは、結局CBEとPowerXCell8iの2種類しかなかったので、「特定のインプリメンテーションに関するドキュメント」というのはつまり、Cell Broadband Engine^(TM) Programming Handbook Including the PowerXCell 8i Processorのことである(以下Handbook)。


Handbookの「8. リソース割り当て管理」を見ると、

Cell Broadband Engine Architecture(CBEA)プロセッサ1のリソース割り当て管理(RAM)機構では、管理対象リソース(メモリ・バンクおよびI/Oインタフェース)の時間の一部を要求元(PowerPC Processor Element [PPE]、Synergistic Processor Element[SPE]、またはI/Oデバイス)に割り当てることができます。

とか書いてあって、バスリソースを確保できるみたいなことが書いてありますね。こっから先は読んでないので知らん。


組み込み向けといわれるARMですら、バスリソースについては、ドキュメンテーションされてないのに、その点、CBEなら、

  • アーキテクチャレベルで、なんらかのリソース配分機構があること
  • CBE/PowerXCell8i の実装で、I/O、メモリバスについてリソース配分ができること

が、ドキュメンテーションされてるし、大変素晴らしいですね。


メモリオーダリング

上でも書いたけど、PowerPCユーザなら、メモリオーダリングがアーキテクチャレベルで決まってるのは常識だった。


また、x86みたいに、WC/WBとかの即物的な名前が付いてるのではなくて、Guarded、Cache-inhibitという、かっこいい名前が付いてるのもPowerPCならではと言える。まあ、G/Iってそれぞれどういう効果あるのか知らないけど。


それ以外にもCBEの外側からメモリアクセスした時の挙動もちゃんと決まっていて、CBEAの「10.9 I/O アクセスのストレージ順序付け」を読むと、外部からのアクセスは、ちゃんと順序付けられることが保証されてるし、最初に書いたように、「NICから直接SPEのLSに入れて」とか、やった場合でも、全く問題無いことが保証されてるし、「10.2 メインストレージ・ドメインでのアクセス順序付け」とか読むと、「SPEからNICレジスタ叩けば」も、大丈夫なことが保証されている気がしてくるしすばらしいですね。

IOMMU

さて最近は仮想化だなんだと言って、Intel/AMDのCPUにもIOMMUが実装されてますが、それはCBEが2006年に通った道だった。(まあfullvirtとparavirtの違いがあるので公平ではないが)


IOの外側からのアクセスもアドレス変換は、実装依存(といっても以下略)だけど、まあ、一応決まっていて、例えば、PS3だと、CBEのとなりに、GPUが付いてたけど、このGPUを使っても、ハイパーバイザのメモリを読めないようにするとかは実現されている。詳細はHandbookの11.4.1。

仮想化

これはCBE以前にPowerPCアーキテクチャで決まってる。

(あんま関係ないけど、 時々 http://d.hatena.ne.jp/w_o/20100130/1264854010 が参照されてるみたいなのだけど、これ調べながら書いてて結構読みづらいので、書きなおしたいという思いはある。特に図を入れたい)

SPU アイソレーション

コピーガードをつくりたいとか考えたとしよう。PCなら、どうやっても、実行時には命令をメモリにのせておく必要があって、「デバッガで頑張ってよく見る」という作業に勝てないのだが、でもCBEなら、大丈夫!いっぱいNDAにサインして(勝手なイメージです)、IBMSONYTOSHIBAにお願いすれば、SPUアイソレーションを使うことができるのだった。


詳細(の多分半分くらい。実際どうなってるかは僕もよく知らない。)は、↓に書いてあるが、
https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/AEBFE7D58B5C36E90025737200624B33/$file/CBE_Secure_SDK_Guide_v3.0.pdf


仕組みとしては、

  • 全CBEで共通のハードウェアルートキーがCPUに埋まっている
  • それを使って、プログラムをハードウェアで復号化する
  • SPUのメモリを隔離(Isolate)して、OS/ハイパーバイザからも見られないようにする

というものである。


これのよい点は、上のSecure SDK Guideの「4 The Key Hierarchy」に書いてあるが、ごくごく一部の人だけしかルートキーを知らない状態でも、破られない暗号化ができるという点で、

  1. ルートキーを知ってる人が、ソフトウェアで暗号化/復号化プログラムを書く
  2. そのソフトウェア暗号の暗号化プログラムを別の第三者にわたす
  3. ルートキーを知っている人は、ソフトウェア復号化プログラムを、ルートキーで暗号化しておく
  4. 三者が、暗号化されたソフトウェアと、ルートキーを知ってる人が書いた復号プログラム(暗号化済み)を一緒に配布する

と、いうようにすることで、第三者とルートキーを知っている人以外が、復号化できないデータをつくれるし、第三者がヘマをやった場合でも、ルートキーを守り抜くことができる。

具体的に言うと、PS3が完全にクラックされた場合でも、CBEのハードウェアルートキーを守れるというわけである。


実際にPS3のキーの構造がどうなってるかは、 http://www.ps3devwiki.com/wiki/Boot_Order を読むと、わかるかもしれない。まあ、ちゃんと読んでないのでよくわからんけど…

プロブレム・ステート・メモリマップド・レジスタ

GPUだと、MMIOレジスタが隠蔽されてて、ホスト/デバイス間で、細かい同期ができないのだが、CBEなら…そう、もちろんOKさ。


CBEAの「8. プロブレム・ステート・メモリマップド・レジスタ」を見てほしいのだが、

プロブレム・ステート(PS)・メモリマップド・レジスタは、プロブレム・ステートで実行中のアプリケーションがアクセスできる機構一式を定義しています。

と、書いてある。


プロブレム・ステート、というのは、PowerPC用語で、OSではない、ユーザアプリケーション用の状態のことを言うのだが、つまり、CBEでは、OSがSPEを制御する用のレジスタと、アプリケーションがSPEを制御する用のレジスタが分かれていて、ユーザ空間から、MMIOを直接叩いて(オーバーヘッド0で)、SPEと通信することが可能である。


表8-1に一覧があるが、知っておくと便利(?)なのが、

の、ふたつで、

メールボックスは、32bit値をやりとりする時に、シグナルは、1bit値を送信する時に便利だった記憶がある。


PPE側は、メモリポーリングするか、OSの力を借りて(オーバーヘッドがそこそこある)割り込み付きのメールボックスを使うしかなくて、やや無駄があるが、SPE側は、メールボックスが空の時にメールボックスへアクセスすると、ブロックするようにできていて、電力やバスを無駄遣いしないようにできている。また、データが来たら割り込みを入れるとかもできる。レイテンシは詳細データ手元に無いけど、メモリポーリングより、わずかにオーバーヘッドがあるくらいだったと思う。


これを使うことで、無駄無く効率良く、PPE/SPE間、SPE/SPE間の細粒度同期が実現できるしすばらしい。

割り込み

まあ割り込みはちょっと手抜きだな。最低限、SPEに外部割り込みが入れられるようにして、その上で割り込み時間保証とかやっとくべきだった。

まとめ

アーキテクチャ素晴らしいからといって普及するわけではない。


CPUつくりたいという人は、CBEA 10回ぐらい読んで、その機能が何を実現してるかとか考えるべきだと思いますね。