
エミュレータ移植のWii版マリオ64、浮動小数点演算の関係でオリジナル版とは挙動が異なることが判明 58
ストーリー by hylom
浮動小数点の罠 部門より
浮動小数点の罠 部門より
エミュレータを使って移植されているWii版のスーパーマリオ64では、特定の場所の「揺れる足場」の挙動がオリジナルのNINTENDO64版とは僅かに異なるという。その原因は、64ビット浮動小数点演算結果を32ビット浮動小数点に変換する際の処理が異なる点にあるそうだ(なぜWii版マリオ64で長時間放置すると足場が浮かび上がるのか(非技術者向け解説))。
ことの発端は、ゲーム内でジャンプ操作を行うための「Aボタン」を押さないでステージをクリアするという縛りプレイを行っているプレイヤー達による研究で、「ほのおの うみの クッパ」というステージではWii版に限り長時間待つと「揺れる足場」が浮き上がっていくことが分かったという(AUTOMATON)。
これは、足場の揺れ具合を計算する処理において64ビット浮動小数点数を32ビット浮動小数点数に変換する際に僅かに丸め誤差が発生し、それが累積することによるものだという。縛りプレイヤーたちはこれを利用して足場を十分な高さまで浮上させることで、Aボタンを押さずにステージクリアを達成することにチャレンジしているようだ。
「Aボタン」を押さないでステージをクリアするという縛りプレイを行っているプレイヤー達 (スコア:2, おもしろおかしい)
世の中想像もつかない事をしてる集団が存在するんだな~
Re: (スコア:0)
【ロマサガ3】セレクトボタン禁止RTA(Real Time Attack) [nicovideo.jp][不快と思う方が多い表現が多々あるので閲覧注意]に比べればまだ人間が想像しやすい縛りだと思います。
Re: (スコア:0)
現在進行中のサガフロ2最小ターンTASではその手の表現がほとんど影を潜めているところを見るとやっぱり不快に思う人が多かったんでしょうね。
Re: (スコア:0)
元々が相手を不快にさせておちょくる文化の産物だから、不快に思う人は多くて当然なんだけどな…
にもかかわらず流行りだとか荒れればコメントが稼げるとかで使うバカは大勢いるってのが嘆かわしい。
元々が荒らしの性質を持ってるから、止めても同類の名の下に持ち込まれて足を洗うのも難しいとかホントやな文化。
メーカー移植物はだいたいそう (スコア:2, すばらしい洞察)
PSシリーズのナムコミュージアムもだいたいダメ。
結局MAMEが一番オリジナルに一番近い。
Re: (スコア:0)
エミュレーションの甘さってのはどんな環境でも起こりうることだと思うけどね。
Re: (スコア:0)
趣味人が完全再現を頑張るMAMEと、商売で再現度と売り上げ、開発費のバランスを考えるメーカの違いじゃないかな?
Re: (スコア:0)
BGとOBJの表示タイミングの違いも考慮されないMAMEがオリジナルに近いってww
丸めのやり方の差異らしい。 (スコア:1)
WiiのVCがどういう実装になっているか知らんけど
CPUからまるまるエミュレーションしていなくて、
ライブラリ(BIOS?API)の実装違いの様な気がする
切り捨てか四捨五入かというより、
0捨て1入とか最下位ビットの扱いの差異じゃないかな
Re:丸めのやり方の差異らしい。 (スコア:1)
タネを明かせばなるほどだけど、
最初に試した人は予測を立てて放置したのか、解析した結果わかったのか、寝落ちして目が覚めたら浮いていたのか。
Re:丸めのやり方の差異らしい。 (スコア:2, 興味深い)
> ゲームを起動したまま3日間放置すると、足場が十分な高さまで浮かび上がり、Aボタンを押さずとも次の足場まで進めることができます。
だいぶ長いこと寝落ちしたんだな。
Re: (スコア:0)
8時間分くらいでも見た目でわかるくらい浮かぶのでは?
Re:丸めのやり方の差異らしい。 (スコア:2, 興味深い)
リンク先にある解説動画では一晩放置したプレーヤーが気づいたと言っているので、寝落ちっぽいね。
設計がおかしいのか? (スコア:1)
浮動小数点演算の規格IEEE754では複数の丸めモードが定義されているが、同じ丸めモードだったら処理結果は完全に一致するのではないのか?
それともIEEE754とは無関係に独自実装したのか?
Re:設計がおかしいのか? (スコア:5, 参考になる)
リンク先でたどれるGoogleドキュメントの [google.com]「Wii VC Rounding / BitFS Platform Drift」という項目によると、
とのことで、CPUへの命令の変換の仕方に問題があるとのことです。
# SM64の意味が解らず、Google先生に聞いたらSuper Mario 64だと教えてもらった
Re: (スコア:0)
PowerPCのstfsを使わずに最近接丸めをソフト処理すりゃ直る程度の話かな。
Re: (スコア:0)
それよりは、計算誤差でどんどんズレるソフトの設計がマズいんじゃないかと。
Re: (スコア:0)
基本短時間のアクションゲームだからOKとするのはあり得るけど、この件はどうなんでしょうね。
Re: (スコア:0)
uint32のカウンターを1フレーム、1/60秒毎に++しておいて、キャラの動きやフェードイン、フェードアウトその他、あらゆる演出はそのカウンターの進み具合を基準に動かす、という実装が便利で楽。
ただこれ、だいたい2年ちょっとでオーバーフローして0に戻るので、その瞬間に表示が乱れる。
いくつかの場面でデバッガでオーバーフローの瞬間を再現してみて、大した事は起こらなさそう、ぐらいまでは試したけど、ゲーム中のあらゆる場面で大した問題が無いと試すのはテスト工数が多すぎて諦めた。
Re: (スコア:0)
設計は最近接丸めを想定していたのにエミュレーションの実装が不完全なのが悪い(まあ普通問題になることではないが)
Re: (スコア:0)
この丸めだから、どんなに計算を繰り返しても誤差は想定内に収まる、と証明するのは相当難しそうだと思うけど。
問題になってる程度のプログラムなら、1周期分計算したら丁度同じ値になった、他の値は取りえない、これで大丈夫、ぐらいで証明できる可能性もあるけど。
もし、そういう分かりやすい性質がなかったら、かなり大変。
ちゃんと証明できるとしたら、ガチの数値計算の専門家ぐらい。
(まともな大学の工学系だと、カリキュラムのどこかで、計算誤差の注意点については習うはず。
浮動小数点数の計算順序を変えただけで誤差が大きく変わってくるとかそういう。
プログラマなら誰
Re: (スコア:0)
元ゲームプログラマですが、そのとおりですね。
元のマリオ64の作りが良くないです。
現在位置に加減算して上下動させると誤差蓄積でずれや歪みが発生するので、
本来は固定の基準点から相対的に上下動させるようにします。
Re: (スコア:0)
実機での誤差が累積して0になることを想定の上でコード書いてたら、
移植を想定しないゲームのコードとしては問題ないんじゃないかな。
Re: (スコア:0)
> 移植を想定しない
スーファミにもスーパーゲームボーイがあったくらいだから、移植やエミュの想定をしてないとは思えないな。
OSのバージョンが変わると動かなくなるアプリのように、不用意な作りではあるだろうよ。
メンテナ泣かせ。
Re: (スコア:0)
想定なんてできないってばよ。
丸め方法の違いも、「誤差が蓄積するやつ」と「蓄積しないやつ」じゃなく、
「誤差が蓄積するやつ」と「それよりは誤差が蓄積しづらいやつ」ぐらいの差しか無い。
デバッガで入念にチェックすれば、運良く誤差が蓄積しない動作になってる事を確認できるかもしれないし、
確認出来ればゲームの実装としてはそれで十分だと思うけど、
確認に相当な手間が掛かるから、1クロックでも早く動くプログラムにしたい、とかの強い動機でもない限りはお勧めできない。
Re: (スコア:0)
一般論と個別論の区別がついとらんね
「ある」プログラムについて誤差が蓄積しないことを確認するには「それ用」の検証プログラムで十分
デバッガでやるやつはバカ
ゲームプログラマにはクロック削りのような目先のことしかできないバカが多い印象があったがまた一つ裏付けられた
Re: (スコア:0)
CPUの命令はよくわかりませんが、
stfsの前にfrspとかいう命令つかって丸める必要があったのかと
Re: (スコア:0)
エミュレータって、大抵は性能ぎりぎりの状態で開発がスタートするので、挙動が異なるのを承知で速い命令を採用することも少なくないと思います。
現在のCPUでも丸めやデノーマルの処理方法の変更には大きなペナルティがあったりするので、仕方なく標準ライブラリと合わせていることもあるでしょう。
Re: (スコア:0)
縛りプレイなので9じゃなくて4の形になってます
Re:double-rounding (スコア:2)
あなたの言ってるような内容は #3423345 は(おそらく)理解してる。
むしろあなたのコメントほうがIEEE754の概要を理解してるように見えないんだよね。
# mishimaは本田透先生を熱烈に応援しています
Re: (スコア:0)
「複数の丸め」の解釈から
double-rounding
異なる桁で複数回四捨五入
が出てきたんだろーか。
# IEEE754でなく日本語(の中の論理構造)を理解できていない?
Re: (スコア:0)
同じ丸めモードなら同じ処理結果になるのでは、という親コメントの単なる日本語を理解出来てない人がまだなんか言ってる
# 答えとしては他の人もリンク先にも書いてるけどCPUが変わったので別のモードを選んだ
Re: (スコア:0)
何言ってんだこいつ
Re:double-rounding (スコア:2)
Re: (スコア:0)
計算結果が正しくないと
計算結果が等しくないの違いがわからんアレかもしれん
Re: (スコア:0)
> 今50台の日本人
しばらく放置してると台数が増えてくのかな?
Re: (スコア:0)
むしろメンテ不可で壊れていきそう
Re: (スコア:0)
逆走したり、地形に突っ込んだり
Re: (スコア:0)
四捨五入と言ってる時点で丸め誤差が解っていない人ですよ
Re: (スコア:0)
このコメントに今年の残念なおっさん大賞をあげよう。
Re: (スコア:0)
こういうの技術屋として最高に恥ずかしいね。 [hardware.srad.jp]
非技術者向け解説 (スコア:0)
りんごとみかんみたいな説明してるのかと思ったら、単に二進数から説明してるだけか。
これ非技術者は理解できるの?
Re: (スコア:0)
そもそも浮動小数点演算の一般論を述べているだけでぜんぜん解説になっていない
Re: (スコア:0)
固定小数点の範囲で終わってるのに「浮動小数点の説明」と言ってるのは引っかかりましたが、
ここでの肝は、「小数を正確に表現することは(ほとんどの場合で)できなくて,誤差が累積するような使い方をするとズレていっちゃうよ」ってのが判ればまあいいんじゃないかと思う。
Re: (スコア:0)
一流の数学者だって技術者ではないのだからいいんじゃない?
非技術者向け解説とやらを見てみたけども (スコア:0)
> そもそも移植なのにどうして食い違いが発生したのでしょう。実は64とWiiでは使っているCPUが違い、64は「MIPS」というCPUを使っており、Wiiは「PowerPC」というCPUを使っています。そして、Wiiに移植するときに、64bitから32bitに丸める命令を、挙動が違うものを選んでしまったようです。
「64bitから32bitに丸める命令を、挙動が違うものを選んでしまったようです」て説明ではMIPSやPowerPCでは浮動小数点データのフォーマット変換の命令が丸めモード毎に別になってるような印象だが本当?
知らんけどMIPSでもPowerPCでも丸めのやり方なんてFPUへのモード設定とかで決まるんじゃねぇの? 眉唾な記事だなあ。
Re: (スコア:0)
CPUの違いを理解しないで移植しちゃうとあり得る話ですよ。
これはいいニュース (スコア:0)
デッドオアアライブの垂れ巨乳もほおっておけばいいの?
Re: (スコア:0)
十分に待つと髪が逆立ちます
Re: (スコア:0)
次からは堅いそうだから垂れないんじゃないかな
しかしシリーズ当初からの売りを捨てるとは…