判定差のお話2
2019.06.01
前回のつづき

・ボタンのポーリングはVSYNCに同期する(GPUクロック基準)。ちなみに処理落ち時はポーリングしないらしい。
・判定処理はVSYNCに同期して行われるが、判定基準はフレーム数ではなくタイマー(厳密には全然違うがイメージとしてはミリ秒単位の現在時刻)基準で判定する。

というわりとギルティな仕組みが見えてきました。

まあこれだけでは説明できない現象もあるんだけども、少なくとも筐体1と筐体2で判定差が発生する可能性は大いにあり得る話です。

ところで実際、この、「製造個体差」ってのがどのくらいあるのか、っていう話になるんだけども、手元のNu基板2台を実測した結果、

基板1:VSYNC=60.0014Hz
基板2:VSYNC=60.0023Hz

と、なってました。ちなみにきちんと校正されてる測定器ではないので、実際の値としてどのくらい信憑性があるかというのはありますが、相対的にどのくらい変わっているか、という指標にはなるとおもいます。
ちなみに、HDMIを測定するような測定器は持っていないので、DVI-IのアナログVSYNC出力の測定値です。

基板1が60Hzに対して+23ppm
基板2が60Hzに対して+38ppm
で、差は15ppmです。これがワーストケースなのかは解りませんが、実際のところこのくらい変動はするようです。
15ppmなので、以前に書いた水晶振動子の製造誤差±30ppmからみても妥当な範囲かと思われます。

さて、ではここまでの流れの整理です。

・定数値の整理
判定の基準となる時間に関する定数です。2進浮動小数点なので10進の小数表記にした場合、かならず丸め誤差が発生します。
フレーム数換算としたとき、誤差がどのくらい出るのかを確認します。

0.03 ≒ 1.8/60-(9/13421772800)
0.07 ≒ 4.2/60+(1/ 3355443200)
0.10 ≒ 6.0/60+(1/ 671088640)
0.13 ≒ 7.8/60-(1/ 209715200)
0.167≒10.0/60+(1/ 201326592)
0.017≒ 1.0/60+(7/ 8053063680)

誤差(式の右側に分母がやたら大きい分数で書かれている部分)で、一番大きい値は、
(1/201326592)
です。
DIVAをする上で、1曲あたり240秒として、この誤差が積算したとしても、
(1/201326592)×240=5/4194304秒
フレーム数に換算しても、×60で、
75/1048576=0.00007フレームなので、まあ1曲でこの程度の誤差なら無視できるでしょう。たぶん。
なので、定数値はすべて上記に記載のフレーム数として考えます。

・想定される動作
基本的に焼き直しな内容ですが、より具体的に書いてみます。
まず、曲開始時に、VSYNCとタイマーとポーリングは一旦同期するとします。
※一番最初にVSYNCに同期してタイマーを取得して、そこからの差分時間で判定する前提(未確認、この前提の確証を取らないと…)。

ここでは計算しやすくするためにbpm=120とし、四分音符ノーツとします。
四分音符ノーツは必ず開始から0.5秒単位のところがジャストタイミングになりますね。
なので、VSYNCとタイマーが正確に同期していれば、必ず30フレーム単位で現れることになります。

bpm120なので、10拍でMAX BOUNSになります。厳密に言うと10拍+1fpsでMAX BONUSです。
HOLD開始の10拍後に押し直しノーツがあった場合、図のタイミングだと早Cで入ってMAXを取った後、遅Cを取れる計算になります。

本来であれば、bpm=120なので、VSYNCタイミングとジャストタイミングの位置関係は崩れません(図※A箇所)。

※クリックで拡大

ここで、VSYNCが若干遅い、もしくはタイマーが若干速いという誤差を持った状態を考えてみます。
そうすると、VSYNCからジャストタイミングまでの時間が徐々に短くなっていきます。
図にすると下記です。

※クリックで拡大
C-C MAXがどう頑張っても入らなくなりましたね。

これが現時点で考えられる、判定差の要因です。

さて、この現象が起きる原因は「GPUクロック」と「タイマー」の誤差の大きさによります。
単純に大きければ大きいほどおきやすいのではなく、誤差が特定の範囲の場合、特定のノーツに影響を及ぼす、となります。

なので、理論上「曲AのC-Cが入りやすい筐体は、曲BのC-Cも入りやすい。でも、曲CのC-Cは逆に入らない。そして曲CのC-Cが入る筐体は、曲DのC-Cも入れやすい」という現象になると思われます。

さてここで先日紹介したガチ勢による検証動画ですが、

どうやら本当にそういう分類別けがされるようです。何傾向か、というのが恐らく誤差量によって決まってくるのかと思います。
コード解析からたどり着く理論上の予想と、ガチ勢プレイヤーの体感(?)による結果が同じって凄いと思うよ・・・。

そして、この原因となるVSYNCタイミング(≒ポーリング/判定タイミング)とタイマーの誤差を体感ではなく明確にどうやって(デバッガーとかを使わないで)実機で確認をすることができるか、という事になりますが、

・描画はVSYNCに同期して行われるが、針の角度・飛んでくるノーツの位置はタイマーを基準に計算される
→「今のVSYNCタイミング」から、「ジャストタイミング」までの時間(フレーム数ではなくタイマー基準)を元に描画

というところだと思います。なので、判定が異なる条件では、針の角度・飛んでくるノーツの位置が異なるはずです。

というのもまた、どうやら既出の情報のようです。




ところで、最初に規定した、「曲開始時に、VSYNCとタイマーとポーリングは一旦同期する」について、
もしこの前提が崩れた場合に何が起こるかというと、
毎回VSYNCとポーリングの位置関係が崩れる、ということです。
ちなみに、位置関係が崩れて始まったとしても、プレイ中にずれていく位置関係の速度は変わりません。
なので「この台はC-Cが入るときもあるが入らないときもある」となります。
仮に最初に同期しなかったからといって、この現象が発生しないわけではなく、筐体差として判別しにくくなる、というだけですね。

とまあ、判定差の原因の一つについてわりと掘り下げれた感じはありますが、これでも説明が付かない挙動はあります。
ステージ差・PV分岐差がまったく原因不明です。
起動差についても、仮にプレイ開始時のタイミング同期処理があった場合は発生しないはずです。

うん、まったく原因不明なのは解析のしようが無い。
次はとりあえずプレイ開始時のタイミング同期処理の確証を探そうかな。
2019.06.01 22:36 | 固定リンク | ミク | コメント (0)

- CafeNote -