サターンの3D性能
目次
ジオメトリ演算
さて、SGL でも、この「基本」に従ったプログラムを作ればよいようになっています。
この際、ゲームの処理中でポリゴンの表示を行いたい場合は「3次元座標の中にポリゴンを置く」という指示だけを行うようになっていました。
プログラマは、ジオメトリ演算の内容も、演算後の結果も気にする必要はありません。…というか、知ろうと思っても知ることができないような仕組みなのです。
SGLにポリゴンの表示を指示します。プログラマーは、「SGLが計算してくれる」と思っているでしょう。でも、実はSGLのポリゴン表示関数は計算をせず、渡された値をメモリに格納するだけで、すぐにゲームの処理に戻ってしまいます。計算結果を知ることができない、というのはそのため。
計算を行うのは、サブCPUの仕事です。「使われていない」と噂される、サブCPUです。サブ CPU は、メモリに積まれたデータを発見すると、即座にジオメトリ演算を行います。
先にジオメトリ演算にかかる時間を示しましたが、この計算は SH2 にとっては非常に大変なものです。サブ CPU に計算を任せ、メイン CPU はこの間にも「ゲームの処理」をすすめます。
ゲームの処理が進むと言うことは、表示するポリゴンデータもどんどん作り出されると言うことです。サブ CPU は休む暇がありません。
…それどころか、実はこの方法では計算が間に合わないのです。サブ CPU の仕事量が多すぎて、メイン CPU の方が先に仕事が終わってしまう場合があります。
メイン CPU は、すべての「ゲームの処理」が終わった時点で、画面描画が終わるのを待ちます。この際、プログラマは「画面表示が終わるまで停止」というSGLの機能を呼び出すようになっています。プログラマーとしては「CPUを停止する」つもりですが、実はここからがSGLが大活躍する時間です。
サブ CPU だけでは間に合わず、メモリに置かれたままの 3D計算の指示を、メイン CPU も使ってどんどん計算していきます。
ジオメトリ演算が全部終わっても、まだ終わりではありません。計算の結果を Z 軸に従って並べ替え、VDP1 が描画できるようにコマンドとして整えます。
この間、すべてメインとサブで協調し、迅速に演算を行うのです。
これらが終わったら…タイミング合わせのために「画面描画終了」までまって、メイン CPU の処理を再開してしまいます。
次の画面をセットするのはサブ CPU の仕事。この間に、メイン CPU はできるだけゲームの処理を進め、サブ CPU のために仕事を用意するのです。
いよいよサブ CPU が画面描画処理から解放されたときには、すでに 3D 演算の仕事が待っている、と言う寸法。
ゲームを作るうえで絶対に必要な「画面表示終了待ち」はありますが、それ以外の時間は2つの CPU は一切遊んでないのです。
サブCPU実行命令
SGLには、明示的に「サブ CPU にプログラムを実行させる」という命令がありました。命令に対してプログラムのアドレスを渡すと、そのアドレスに置かれたプログラムを、サブ CPU の空き時間に実行させます。
「空き時間に」ですので、いつ実行されるかはわかりません。この命令は、先にあげたような「サブ CPU の仕事」を次々切り替えるために内部で使用されていたものを、何かに使えるかもしれないのでプログラマーに開放しただけです。
開示されている情報も少なく、ほとんど使われなかったと思います。その一方で、「サブ CPU にプログラムを実行させる」と明示的に書かれた命令だったので、この命令を使わない限りサブ CPU は使われないのだ、と思っているプログラマも多かったようです。
「セガサターンは事実上シングルプロセッサとして使われていた」という都市伝説は、おそらくこのために生じた誤解です。
SGLは、別にポリゴン専用ではなく、2Dで使っても便利なように作られていました。前回書きましたが、2Dゲームでも「スプライトの描画順序」は非常に重要ですが、SGLではスプライト描画の際も、Zソートの機能を使って順序を整えることができました。
変形スプライトをいちいち計算しないでも「回転」させられる機能もありましたし、設定が難しい回転BG面を簡単に設定できる機能もありました。ゲーム作成上あると便利な「数学関数」の提供や、音楽ドライバとの連携機能などもSGLの持つ機能の一つでした。ともかく2Dでも3Dでも、ゲームに必要なものはちゃんと入っている、と言う状態です。
SGLは、セガ社内では完成前から使われていたようですし、完成後はサードパーティにも積極的に提供されました。そのため、最初期の頃を除くほとんどのゲームで使われたのではないかと思います。
つまり、都市伝説で伝えられる「事実上のシングルプロセッサだった」というのは事実に反するのです。
2014.10.20 追記
SGLは「ほとんどのゲームで」と言うほどには使われていなかった、という証言を頂きました。
もう一つのライブラリがあり、そちらも多く使われていたとのこと。ほとんど、と書いたのは僕の事実誤認だったようです。
お詫びと共に訂正いたします。
詳細は、別記事としてまとめました。
「CPU が2個だから性能2倍、とはいかず、1.2倍から1.4倍、よほどうまくいっても 1.8倍程度の性能しか出なかった」という説もあります。
まぁ、これは当然です。今の Windows などのマルチプロセッサでも、2個になったら2倍、とはいきません。
マルチプロセッサ時に性能が出ない最大の原因は、バスアクセスにあります。複数の CPU が同じバスに接続されるため、バスを奪い合うことになり、片方が停止してしまうのです。
特に、大きなプログラムで、分岐することが多いと大変です。最近の CPU には「キャッシュ」という、一度読み込んだ内容を覚えておく仕組みがありますが、大きなプログラムや頻繁な分岐に弱いのです。
プログラムは「一番頻繁に読み込むデータ」ですから、キャッシュが利かなくなると頻繁にバスアクセスが発生します。これを複数の CPU でやると、バスの奪い合いが発生して性能が低下するのです。
SGLでは、サブ CPU のプログラムは主にジオメトリ演算しか行いません。先に書いたように、ジオメトリ演算の速度を上げることはセガサターンの生命線でした。そのため、SGLのジオメトリ演算部分は直接アセンブラで書かれ、キャッシュに完全に収まり、可能な限り高速に動作するようになっていました。
ですから、SGLを使っている際には、サブ CPU がプログラムを読み込むためにバスアクセスする、ということはありません。メイン CPU のプログラム読み込みを阻害して性能を落とすことはないのです。
ジオメトリ演算に使用するデータは読み込みが発生しますが、計算時間の方が長いため、アクセス頻度は低いです。つまり、データを考慮してもバスの奪い合いはほとんど起こりませんでした。
そして、もともとゲームプログラムでは「画面描画終了待ち」があるため、CPUが1つでも「何もしていない時間」が発生します。性能を完全に引き出すことはあり得ません。
SGLでは、この「待ち時間」すら利用し、2つの CPU が最適に働けるようにしていました。それを考慮すれば、2つで2倍、と言い切っても良いほどのフル稼働だったように思います。
最後に、SH2 が2個フル稼働している前提でポリゴン数を計算してみます。
途中で、CPU が1つの場合、すべての計算時間をジオメトリ演算に使った場合には19万頂点、ゲームの処理に半分程度の時間がかかったとして10万頂点、としました。
CPU が2個なのだから、片方はジオメトリ演算に専念し、もう片方がゲームを動かす…とすると、単純に足して29万頂点ですね。1頂点で1ポリゴン出るわけではないので、2割引きにすると 23万ポリゴンです。
プレステの公称値は頂点計算150万ポリゴン(450万頂点)で、表示は公称 36万ポリゴン…。セガサターンがフル稼働で頑張っても、まだ勝てません。
まぁ、どちらも「ピーク性能」を想定しているので、実際の表示性能はもっと低いわけですが、それはサターンだって同じです。つまり、サターンはジオメトリ演算の性能ではプレステに勝てない!
先に書いているように、ジオメトリ演算以外の性能…ポリゴン描画などは、今見ても互角の勝負だと思います。サターンは半透明などで弱いのだけど、テクスチャは歪みがなく美しい。描けるポリゴン量はプレステの方が少し多く、サターンは背景画面でそれを補える。
そして、プレステが突出している頂点演算性能も、最終的には表示性能が追いつかなくて活かしきれていない。本当に互角の勝負なのです。
じゃぁ、なんでサターンは負けてプレステは勝ったのさ、というのは、性能とはまた別の話。性能互角なら、別の部分が勝っていたほうが勝つ、と言うだけのことです。これは後日お話できれば、と思います。
でも、次回はまだその話ではなく、SH2 が選ばれた理由について考察します。
参考文献 | |||
Saturn FAQ | Saturn-FAQ編集委員 | 1995 | |
PSXDEV | PSIO / PSDEV | 2011 | |
SH-1/SH-2/SH-DSP ソフトウェアマニュアル | ルネサスエレクトロニクス | 2005.1 | |
その他、WEB上の各種ページ |