スーパーファミコンをエミュレートするのに3GHzが必要なのはなぜでしょうか?主要なスーファミの背後にいる人物…
作成者:BYUU
投稿日:2011年8月9日 23:00
----------------------------------------------------------------
古いゲームをプレイするためのエミュレータはネット上で絶大な人気を誇っており、どのエミュレータがどのゲームに最適かについて定期的に論争が勃発している。今日は、スーパーファミコンのエミュレータ「bsnes」を開発した紳士による別の視点を紹介しよう。彼は、エミュレータ体験の最も重要な部分である「精度」についての考えを共有したいという。
現代のPCで任天堂やスーファミのゲームをプレイするのに、それほど大きな能力は必要ない。1990年代には、エミュレータはわずか25MHzの処理能力でそれを実現できた。しかし、それらの古いゲーム機を正確にエミュレートするのは、まったく別の課題だ。正確なエミュレータが古い技術を忠実に再現するには、最大3GHzの処理能力が必要になるかもしれない。この記事では、エミュレータにとってなぜ精度が重要なのか、そしてなぜそれを達成するのが難しいのかを見ていこう。
簡単に言えば、精度とは、エミュレータ・ソフトウェアが元のハードウェアをどれだけ模倣しているかの尺度である。見かけの互換性は、古いゲームが新しいエミュレータで動くかどうかという、最も明白な精度の尺度だが、そのような狭い視野では、多くの小さな問題を覆い隠してしまう可能性がある。実際のところ、ほとんどのソフトウェアはタイミングの問題に対して非常に寛容に動作し、タイミングが20%程度ずれていても正常に機能しているように見える。
では、基本的な互換性を達成できるのであれば、速度という大きな犠牲を払ってまで精度を向上させる必要があるのだろうか?理由は二つある。
まず、性能だ。『スピーディー・ゴンザレス』の場合を考えてみよう。これはセーブ機能のないスーファミのプラットフォーマーで、だいたい2~3時間の長さがある。一見すると、どのエミュレータでも問題なく動くように見える。しかし、ステージ6-1に到達すると、正確なエミュレータと高速なエミュレータの違いをすぐに見分けることができる。レベルをクリアするために必要なスイッチがあり、そこで稀なハードウェアのエッジケースがエミュレートされていないと、ゲームが行き詰まり状態になってしまうのだ。3時間の進捗が即座に失われ、無敵のゲームに直面したときの挫折感は想像に難くない。ソフトウェアがハードウェアとまったく同じ方法ですべてを実行しない限り、ゲームは壊れたままだ。
あるいは、航空機の下に影が描かれる「デザートファイター砂の嵐作戦」を考えてみよう。これはミッドスキャンラインのラスターエフェクトを使って行われるが、これをエミュレータで再現するには非常に多くのリソースを必要とする。しかし、ラスターエフェクトがなければ、下のスクリーンショットのように、航空機の影は表示されません。特に、影があるはずだと知らない場合は、見落としがちだ。しかし、実際に見てみると、かなり役に立つことがわかる。自機には爆弾を投下する能力があり、この影は爆弾の着弾位置を決める一種の照準システムとして機能する。
第二の問題は保存性だ。任天堂のゲーム&ウォッチのハードを見てみよう。1980年にデビューしたこれらのデバイスは、現在までに4300万台生産されたが、そのほとんどが経年劣化で故障しているか、破壊されている。今でも比較的入手は可能だが、追加生産されることはないため、その希少性は増すばかりだ。これと同じ問題は、どのハードウェアにも当てはまる。その時点で、エミュレータはそれらの古いゲームを体験する唯一の方法となるため、それを正確に行うことができるはずだ。
しかし、この精度には重大な代償が伴う。エミュレータの精度を2倍にすると、動作速度はおよそ2倍になり、その精度をさらに2倍にすると、動作速度は4倍になる。同時に、ほとんどのゲームはエミュレータの精度がそこそこであれば「プレイ可能」に見え、感じられるため、この精度に対する見返りはすぐに減ってしまう。(ほとんどのエミュレータは、最適な性能で95%前後の互換性という「スイートスポット」を目標としている)。
精度は低くても速度が速いエミュレータが悪いわけではなく、そのようなコードは携帯電話や携帯ゲーム機のような低性能のハードウェアでも動作する。このようなエミュレータは、バッテリー寿命が気になるラップトップでの使用にも適している。しかし、精度にもこだわるべき点があり、私自身の仕事でもそれを試みてきた。これが私にとって重要な理由だ。
ソフトウェアで実行する
90 年代後半、Nesticle はシステム必要条件が約 25 MHz で、NES エミュレーターの選択肢として簡単に選ばれていました。この性能には大きな代償がかかった。ゲーム イメージは、このエミュレーターでのみ実行できるようにハッキングされていたのだ。ファンによって作られた翻訳版やハッキング版は、実際のハードウェアでも他のエミュレータでもゲームがプレイできなくなるエミュレータの奇癖に依存していて、ある種のロックイン効果を生み出し、それを打破するのに長い時間がかかった。当時、人々はゲームが元々どのように見え、どのようにプレイされるのかは一般的には気にしておらず、この恣意的で人工的な環境でどのように見え、どのようにプレイされるのかだけを気にしていた。
最近では、最も支配的なエミュレータはNestopiaとNintendulatorで全速力を達成するためにそれぞれ800MHzと1.6GHzを必要とする。速度が必要なのは、エミュレータがうまく最適化されていないからではなく、元のファミコンのハードウェアをソフトウェアではるかに忠実に再現しているからだ。
では、これらをシステム必要条件がわずか 350MHz Pentium II システムだった古い N64 エミュレーター、UltraHLE と比較してみましょう。何気ない観察者にとっては、マリオ64が元のマリオブラザーズよりも低い処理能力しか必要としないことにかなり不可解かもしれない。
私のエミュレーションの経験はスーファミの分野で、bsnesエミュレータに取り組んでいる。Nestopiaの背後にある理想に憧れ、このレベルの精度をスーパーファミコンで再現したいと思った。結果的に、精度に対する同じレベルの献身はタイトルによって2~3GHzの範囲まで条件を押し上げることになった。
www.youtube.comTimeCop, 二つのまったく異なるエミュレータ上で
Nestopiaが流行ったのは、そのシステム必要条件が当時としては僅かだったからだが、1997年にリリースしたら悲惨な結果になっていたのは間違いない。私のエミュレータは最終的に市場の半分以上の性能を持つコンピューティング・システムを必要としたため、私は高いシステム仕様の影響とそれが引き起こす反発を目の当たりにしてきた。自分のコンピューターの性能が十分でないことを認めるよりも、プログラムのせいにする方が簡単だが、実際にはソフトウェアでゲーム機全体を偽造するのは徹底的な過程だ。
なぜ精度が重要なのか
では、エミュレータがすべてのゲームを正しく動作させているように見えるなら、なぜそれを改良する必要があるのだろうか?簡単な答えは、私たちがまだ知らないことを改善してくれるからだ。これは、人気のないソフトで特に顕著だ。
例として、ZSNESとbsnesのエミュレータで『ゼルダの伝説』のオープニングのトライフォースが回転するアニメーションを比べてみよう。前者では、CPUが本物のスーファミより40%以上も高速に動作するため、トライフォースが回転を終えるのが早すぎる。これらは些細なことだが、精度へのこだわりがある人なら、うんざりすることだろう。
私は何十ものタイトルで、曖昧な癖のあるものに出会ってきた。正しく、より正確なエミュレータが、実際には「間違った」結果を生み出すこともある。スーパーボンクのアトラクトモードのデモは実際に同期がとれておらず、ほとんどの実システムでボンクが壁際で立ち往生してしまう。また、「スターフォックス」はゲーム中、大幅なスローダウンの問題に悩まされている。これらは確かに望ましい属性ではないが、それでも正しい。不合理な数が不便だからといって、円周率を3に切り捨てたりはしないでしょう?
古典的なゲームを改良可能なものとして扱うことの利点は否定しない: N64のエミュレータは見事な高解像度テクスチャパックと1080pのアップスケーリングを採用し、スーファミのエミュレータはMode7のグラフィックに2倍のアンチエイリアスを、オーディオサンプルに3次スプライン補間を提供することが多い。このようなエミュレータのゲームは、見た目もサウンドも良くなっている。これは悪いことではありませんが、ハードウェアに忠実なエミュレータを書くという目的には反している。このような改善テクニックは一般的に、正確なエミュレータという選択肢を許容することすら難しくする。
精度が利点になるもう一つの大きな分野は訳者、ROMハッカー、自作開発者によるファン制作の作品だ。実際のハードウェアでコードを実行できる人はほとんどいないため、エミュレータを使ってソフトウェアを開発することが多い。残念ながら、速度重視のエミュレータはハードウェアの制限を無視することが多い。これは、商業的に開発されたゲームでは決して問題にはならない。実際のハードウェアでテストすることが条件であれば、バグはすぐに発見され、修正されるでしょう。しかし、特定のエミュレータでしかテストできない場合、そのようなバグは残りがちだ。
いくつか例を挙げよう。『ドラゴンクエスト1・2』、『デュアルオーブ2』、『美少女戦士セーラームーン アナザーストーリー』や『イース4』のファン翻訳版はすべてビデオプロセッサが画面描画のためにビデオRAMをロックアウトしている間に、ビデオRAMに書き込んだ結果、文字が見えなくなるという問題に見舞われた。これらのタイトルのうち、その後、修正されたのは半分だけだ。
このハードウェアの制限については1997年からわかっていて、1行のコード修正で済んでいたが、最も普及しているエミュレータはいまだにこの動作をサポートしていない。その結果、このエミュレータのためだけに作られた翻訳は、問題やロックインを引き起こし続けている。お気に入りのファン翻訳を大量に実行できない、より正確なエミュレータを誰が使いたいと思うだろうか?
それだけではない。元のハードウェアでは、乗算や除算の結果を演算ユニットに求める際に遅延が発生した。しかし、ファンハックによって、ゼルダの翻訳版の音楽が切れたり、スーパーマリオワールドのチェインチャップパッチがおかしくなったりした。
あるいはエミュレータが、サウンドプロセッサがエコーサンプルを共有RAMに書き込むという事実を無視するかもしれない。非現実的なエコーバッファサイズを使用するハックに行き着くまでは問題ありませんが、その結果、メモリ内のオーディオプログラム全体が上書きされ、クラッシュして壮大な炎に包まれることになる。この問題一つで、数十のスーパーマリオワールドのファン自作レベルがプレイ不能になる。
あらゆるゲームのためのエミュレーター
将来、末端使用者が四つの翻訳リストのために「ZSNES v1.42」、さらに六つのROMハッキングのために「Snes9X v1.51」、そしていくつかのあまり知られていない日本のゲームのために「bsnes v080」を必要とするような悪い日が来ることが予見できる。これは負担になる。
エミュレータにも寿命があることを理解しなければならない。ZSNESのように純粋なx86アセンブリで書かれているものは特にそうだ。携帯電話でこれを実行ことはできない。ZSNESでしか動かないようにハックをロックすることは、ハックを無用の長物にしてしまうことになる。Windowsが32ビットの下位互換性を失えば、すでに16ビットの下位互換性が失われたように、これらのファン翻訳やハッキング版は永遠に失われることになる。その時点で、エミュレータそのものが、古いゲームを生かすための手段ではなく、ほとんど別の死んだゲーム機のようになってしまう。
それに、スーファミのゲームは実際のスーファミ機で動くべきだという問題もある。元のハードウェアを完璧に模倣したエミュレータ、あるいはそれに近いエミュレータを作ることで、複数のシステムで動作するプラットフォームを作り、将来のバージョンでゲームやハックを実行できるようにする。ゲームのアイデアだけでなく、スーファミのハードウェアの仕様を生かすことだ。
しかし、本当に3GHz?冗談だろう?
うまく最適化された、速度重視のスーファミエミュレータなら、わずか300MHzの処理能力で全速力で動作させることも可能だ。また、何百もの不明瞭なバグを抱えることになる。
一般的に起こるのは、その問題を特別にハックして回避すること。ZSNESとSnes9Xの両方は、最も人気のある50ほどのゲームの内部リストを持っている。それらのゲームを読み込むと、エミュレータはタイミング値を微調整し、これらのゲームが動作するようにコードの特定の部分を修正する。ゲームそのものを外部からハックしていたNesticle時代よりは改善されているが、最終的な結果がどうであれ、不正行為であることに変わりはない。
最も人気のある20タイトルほどしかプレイしないカジュアルゲーマーは、300MHzを必要とするエミュレータと3GHzを必要とするエミュレータの間に目に見える違いはないから、もちろん前者を選ぶだろう。私は速度重視のエミュレータを尊重し、高く評価しているが、精度に気にする者はこのアプローチが進歩を妨げることを嘆かずにはいられない。より精度の高いエミュレータを使うプレイヤーが増えなければ、エミュレータが対応するすべてのゲームのバグを見つけることはできない。意図された方法でゲームをプレイする人が多ければ多いほど、ゲームごとに特定のコードを修正するのではなく、エミュレータの精度を修正することで、問題が発見され、解決されるにつれて、エミュレータはより優れたものになる。
以下のスクリーンショットは、適しているゲームの好例だ。これは実際には非常に優れたプラットフォーマーなのだが、その名を聞いたことがある人はほとんどいないだろう。これはほとんどの人気ゲームが不正確なエミュレータでも適切に実行できるからと言って、精度が依然として重要である理由を示す好例である。あなたのちょっとありふれていないお気に入りゲームがいつこのようなバグに遭遇するか分からない。以下のスクリーンショットにはスイッチが写っている。他のエミュレータではこのスイッチを押すと、ゲームは即座に行き詰まり状態になってしまう。何が起こるかは次のスクリーンショットで示されている。スイッチがブロックを電界の真ん中に移動させることだ。レベルをクリアするには、つまりゲームをクリアするには、これが条件となる。この記事を書いている時点では、このゲームを完全にプレイできるスーファミエミュレータはbsnesだけである。
スーファミには、高解像度表示モードだけでなく、「pseudo-hires」モードと呼ばれるバリエーションもある。このモードは、スーファミのハードウェア上でレイヤー間の真のアルファブレンディングを作成するのに役に立つ。このモードを無視すると、下の画像にあるように、レイヤーが他のレイヤーを完全に遮ってしまう。
ビデオゲームは私たちの歴史の一部であり、発売当時の「真」の形があるという事実を尊重する必要がある。モナリザのJPEGや月面着陸のRealVideoストリーム、または「Walking in the Air 」のMIDI演奏しかなかったらと想像してみてほしい。私たちには過去を生かし続ける能力があり、それはほとんど義務であるように感じる。
では、余分な2.7GHzはどこに行くのでしょうか?同期
エミュレータの性能を測る上で最も一般的な誤解は、単にプライマリ・プロセッサのクロックレートを見ればいいというものだ。残念ながら、これでは何もわからない。N64のCPUのクロックはスーファミのCPUの35倍かもしれませんが、UltraHLEはZSNESと同じ処理能力を必要とする。
エミュレータの主な要求は一つのプロセッサが他のプロセッサと同期しなければならない1秒あたりの回数だ。エミュレータは本質的に逐次処理過程だ。今日のマルチコアプロセッサに頼ろうとすると、あらゆるタイミングの問題が発生する。ある人が箱を降ろし、別の人が箱をスキャンし、別の人が箱を開け、別の人が商品を並べ始める、といった具合だ。同期というのは、組立ライン全体を停止させて清掃し、新しい製品でやり直すことに等しい。これはスループット(一定時間内の情報処理量)に信じられないほどの打撃を与える。パイプラインやアウトオブオーダー実行の利点を完全に無効にしてしまう。同期する必要が増すほど、それに追いつくために組み立てライン(流れ作業)をより速く動かす必要がある。
ZSNESとbsnesの同期率を比較してみよう:
S-CPU: 600,000 vs 21,477,272 S-SMP: 256,000 vs 24,576,000 S-DSP: 32,000 vs 24,576,000 S-PPU: 15,720 vs 21,477,272 合計: 903,720 vs 92,106,544
まずCPUから見てみよう。CPUは通常3.58MHzで動作していると仮定される。この速度は、1秒間に実行されるサイクル数に適用される。一般的な命令は4~8サイクルを消費し、ZSNESは1命令につき1回同期する。しかし、さらに技術的なことを言うと、サイクルはバスホールド遅延に分解され、生のオシレーターレベルでのタイミングが必要となる。スーファミのCPUオシレーターの定格は21.47MHz。同じことがSMPにも適用され、オシレーターの定格は24.58MHz。
ビデオに関しては、99パーセントのゲームは画面描画中にディスプレイレジスタを変更しようとはしない。このため、スキャンライン全体を一度に描画することができ、262スキャンライン*60フレーム/秒の同期が必要になる。しかし『デザートファイター 砂の嵐作戦』作のようなゲームを実行すると、スキャンラインごとにディスプレイの輝度レジスタに複数回書き込みが行われるため、完全な精度を望むならクロック周期ごとに同期する必要がある。
オーディオに関しては、スーファミの32kHz周波数に合わせてオーディオ速度ごとに1回だけ同期すれば、ほぼすべてのタイトルが問題なく動作する。しかし、『アースワームジム2』のようなタイトルを実行すると、サイクルごとに同期しないと効果音が途切れてしまう。『甲子園2』では定期的にロックがかかることさえある。
従って、bsnesはZSNESより10倍動作が遅いが、文字通り100倍正確なのだ。実際のところ、わずか3GHzでこれができるのは非常に印象的だ。協調型マルチスレッドとjust-in-time同期という、これまでエミュレータで使われたことのない技術を利用したからこそ、bsnesの現在の性能を引き出すことができたのだ。カーネルのスケジューリングは言うまでもなく、ステートマシンではこのタスクには対応できない。
最も直接的な観察は、同期速度が1/100であっても、ZSNESはほとんどのゲームで問題なく動作するという事実だ。否定はしないが絶対的に完璧な同期が要求されることはほとんどない。しかし、実際にはそれが必要な場合もある。スーファミのCPUは遅いため、多くの元のゲームはシステムを絶対的な限界まで押し上げた。
タイミングを完璧に合わせなければ、モグラ叩きゲームを永遠に続けることになる。一つのゲームを修正すると他の2つのゲームが壊れ、それらを修正するとさらに二つのゲームが壊れる。その修正でまた最初のゲームが壊れる。過去15年間の変更履歴を見るだけで、このことが検証できる。
余分なプロセッサのエミュレータ
カートリッジ基盤のシステムの楽しみの一つは、文字通りPCBを直接システムに差し込むことだ。そのため、余分なコプロセッサ(多くの場合、デジタル・シグナル・プロセッサ)をカートリッジに内蔵することができる。これにより、競合他社のタイトルに対してさらに優位に立つことができる。スーファミのコプロセッサで最も人気があったのは、ポリゴンレンダリングとスプライト回転用のSuperFX(『スターフォックス』や『スーパーマリオワールド2』で使用)、3D演算用のDSP-1(『パイロットウイングス』や『マリオカート』で使用)だった。
多くの場合、これらのプロセッサはホストプロセッサから分離されているため、ハイレベルエミュレーション(HLE)を使って実装することが可能だ。これはスーファミのコプロセッサに限ったことではなく、N64のビデオマイクロコードエミュレーションなどでも見られる。
ここでの考え方は、個々の命令を考えるのではなく、命令群全体が一緒に何をするかを考えることだ。言い換えればプログラムを「これらの点に三角形をレンダリングする 」とか「このスプライトをN度回転させる 」といった機能の観点から考えるのだ。そうすれば、実質的にオーバーヘッドなしでこれらの操作をシミュレートできる。残念なことに、この方法は個々の命令の実行に必要なタイミング情報をすべて捨ててしまう。そして何よりも悪いことは、通常は完璧ではないことだ。元の実装にあった軽微なエッジケースや癖、欠陥が失われ、結果的に動作が微妙に異なる。
低レベルエミュレーション(LLE)のアプローチは、DSPを通常のプロセッサと同じように扱い、各命令を一つ一つ実行することだ。ゲームは本来よりも高速に動作せず、エッジケースでもすべて正しく動作する。しかし、これは非常に負荷が高い。スーパーマリオカートは、HLEではコプロセッサを使わないスーパーマリオワールドと同じ速さで動くのに対し、LLEでエミュレートすると25~30%遅くなる。後期『ロックマンX』のゲームに使われているCx4チップは非常に強力で、LLEでは文字通り性能が半減する。DSPは実際非常に強力で、スーファミ時代でも21MIPS以上で動作するのが普通だった。
DSPのプログラムコードを入手するには、集積回路を硝酸で溶かし、電子顕微鏡でチップの表面をスキャンし、染色して手作業で読み取るか、物理的に痕跡を変えてモニターし、プログラムROMとデータROMを取り出す必要がある。このような作業は、非常に専門的な知識と設備が必要なため、チップの複雑さにもよるが、プロに依頼すると数百万ドルかかることもある。ドクター・デカピテーター "と呼ばれる人物の努力のおかげで、私たちは材料費だけで12個近くのチップからこのデータを抽出することができた。
作業が終わったら、DSPは通常1回限りの特殊部品であることを理解する必要がある。命令セットは、バイナリー・ブロブからリバースエンジニアリングされ、事実上まったく文書がない状態でエミュレートされなければならない。これは条件の厳しいプロセスであり、これらのゲームを正確にエミュレートするために必要な献身的なレベルを示している。
十分な正確さは?
正直に言うと、上記に挙げたすべての問題にもかかわらず、正確なエミュレーションはまだ表面をなぞっただけだ。デジタル集積回路エミュレーターであるDICEを例に挙げてみましょう。これはトランジスタレベルで動作し、史上初めて作られたビデオゲームを完璧に再現するエミュレーターである。『ポン』を約5-10fpsで実行するには、DICEは3GHzのプロセッサを必要とする。はい、その通りです。現時点では回路レベルでポンを全速力で実行できるコンピュータプロセッサーは存在しない。DICEは遅いプログラムというわけではない。実際、非常によく最適化されている。トランジスタの伝搬遅延をすべてシミュレーションを行うには膨大なオーバーヘッドがかかるのだ。
しかし、いつかは可能になるでしょう。そして私はこの名作が後世のために完全に再現されたことをうれしく思っている。
しかし、DICEのアプローチをより現代的なシステムに適用するのは問題がある。Visual6502の場合を見てみよう。ある賢い人たちが、任天堂やコモドール64などで使われていた6502 CPUの表面をスキャンするために、私たちのDSP抽出法と同じような技術を使った。彼らはトランジスタをベクトル化し、伝搬遅延を無視したチップの高レベルシミュレーションを提供した。このコードはJavascriptで実演されたことで有名だが、C言語にも移植され、最適化されている。ショートカットを使っても、コンピューターはまだこの実装をエミュレーションに使えるほど高速ではない。
すべてのエミュレータがトランジスタの伝搬遅延をすべて対応することを望んでいるが、実際のところ、これは単純に不可能だ。私たちが生きている間にこのレベルでプレイ可能なフレームレートでN64をエミュレートできるハードウェアが登場することはおそらくないと言っても過言ではない。
実際にスーファミでこれができるかどうかも疑わしい。ある程度、現代のコンピュータの処理能力が、エミュレーターにとってどれだけ正確になるかを決定するのに関係していることは理解している。
私が行った妥協案は、実際のハードウェアに近い大まかな設計を作り、各プロセッサをきれいに分離し、実際のチップが共有する状態だけを共有することだった。実際のハードウェアでのすべての操作の結果と完全に一致させることだが、私のアプローチは少なくとも、実際のハードウェアと事実上見分けがつかないエミュレートされたシステムを作ること。ただし、DICEとは異なり元のハードウェア設計を完全にデジタル化したものではない。
目標はハードウェアを改良することではなく、ハードウェアに可能な限り近づくことだ。
N64以上になると、このアプローチでさえももはや実用的ではないことはわかっている。私はここで簡単な答えを持っているわけではないが、世界で最も強力なシステム上で1秒間に1フレームも実行できないエミュレータを開発することは、現実的に誰にも期待できないことはわかっている。
最後に
私が懸念しているのは、ほとんどの場合、開発者が今日のシステムの利用可能な処理能力の半分を利用することさえ恐れているということだ。古いハードウェアは、最も初期の、最も精度の低いエミュレータのシステム条件にこだわれ、将来のすべての努力のベンチマークとなる。
私は将来より高速なハードウェアが登場することを見越して、現在利用できる性能をすべて、あるいはもう少しだけ活用しない理由はないと思う。古いエミュレータがなくなるわけではない。古くて遅いハードウェアを使っている人たちのために、それらはまだそこに存在している。
より強力なシステムをお持ちの方は、より正確なエミュレータにチャンスを与えてください!開発者はエミュレータの忠実度を向上させるために使用者を切実に必要としていますし、彼らを励ますことのできる聴衆を必要としているのです。