#9やっと*BufferRL | //www.旧型、PSP開発幼稚園.game.jp/(本館)

#9やっと*BufferRL

#9やっと*BufferRL(2006-02/09)



■初めてDGEN100のUpdateOneを見た時から変だなと思っていた。 **Buffer(つまり、*Buffer[2])を、*BufferLRに変更した。 (UpdateOneのみ読むとLRみたいに読める) が、調べたら(始めの予想どうり*BufferRLで)名前が違うので、 *BufferRLに変更した。 つまりここから先はたぶんRLになっているので、直す必要がない。 UpdateOneのみのバグ(RとLが逆)という事が判った。 (だってCDの規格がRLなんだもん。苦労してフィリップスと作った資産なのに、 ソニーがPSPでLRで作る訳ないじゃん。そんな異常な事したら担当者、即首。
やはり、UpdateOneを呼ぶ所が間違ってる。 「mdfr.cpp」 略 else  ←音声をOFFの場合は、音声バッファをクリアする。 (でないと前に使ったゴミを合成して発音してしまう) { // for( i=0 ; i < len /2 ; i++ ) for( i=0 ; i < len ; i++ )   ←どうせ*BufferRLなん だから、一気に2倍(左右両方)処理。 { ((unsigned long*)sndi->r)[i] = 0 ;  ←作った 人は*BufferRLである事を知っている。 //((unsigned long*)sndi->l)[i] = 0 ;  ←*Buf ferRLだから無駄な事はしない。 } } // Add in the stereo FM buffer // FMSAMPLE *buf[2];                    ←これが噂の**Buffer // buf[0] = (FMSAMPLE*) sndi->l;             ←標準のMAMEで はデジタルミキサーやデジタルフィルター等入るので、外部仕様はこの様になっている。 // buf[1] = (FMSAMPLE*) sndi->r;               こういう**Buf ferで実装しとけば、5+1ステレオにも簡単に対応できる。(ソースを直す必要がない) 「ナムコシステム21WinningRun」の様に標準で4chのゲームも世の中には存在する。 (右前、左前、右後、左後、で4ch)これ基盤(’91)持ってるから今度ダンプしなくちゃ(世界中で誰もやってないらしい。「R911」) がPSPでは無駄っていうか。(別にいいけど) // FMSAMPLE *bufferRL = (FMSAMPLE*) sndi->l;   ←元はこっちに なってた。(だから*BufferLRなのかと思った。) FMSAMPLE *bufferRL = (FMSAMPLE*) sndi->r;   ←*BufferRLなんだからこっち。 if( (snd_mute & 0x3F) == 0 ) { YM2612UpdateOne(bufferRL, sndi->len /*, snd_mute*/); }
昨日76496のソースも見たが、この実装なら、さして一緒にしても、パフォーマンスアップしないかも しれない。(やってみなくちゃ判らないが) そんな事をするよりも、先にDACのミキサーを取っ払った方がいいかも。(このソースの直前がDACの ミキサー)
■UpdateOneの外部仕様は、こんな感じになった。
typedef unsigned short FMSAMPLE; 略 /* Generate samples for one of the YM2612s */ //id YM2612UpdateOne( FMSAMPLE **buffer, int length, int flags );    昔の。 //id YM2612UpdateOne( FMSAMPLE **buffer, int length /*,int flags*/)  古いの。 void YM2612UpdateOne( FMSAMPLE *bufferRL, int length /*,int flags*/) 違いが判かるよネスカフェ。 { 略 // FMSAMPLE *bufL,*bufR;  もういらない。 略 /* set bufer */ // bufL = buffer[0];       ここも接続する必要がない。 // bufR = buffer[1];
#define ADVANCE_PAN \ int lt,rt;\ lt = 0 ;\ if( pan0L ){ lt = out_fm[0]; }\ if( pan1L ){ lt += out_fm[1]; }\ if( pan2L ){ lt += out_fm[2]; }\ if( pan3L ){ lt += out_fm[3]; }\ if( pan4L ){ lt += out_fm[4]; }\ if( pan5L ){ lt += out_fm[5]; }\ lt += bufferRL[0]; \ ここはこうなってる。(76496やDACのデーターと合成) \ rt = 0 ;\ if( pan0R ){ rt = out_fm[0]; }\ if( pan1R ){ rt += out_fm[1]; }\ if( pan2R ){ rt += out_fm[2]; }\ if( pan3R ){ rt += out_fm[3]; }\ if( pan4R ){ rt += out_fm[4]; }\ if( pan5R ){ rt += out_fm[5]; }\ rt += bufferRL[1];\ ここはこうなってる。(76496やDACのデーターと合成)
接続はこんな感じ。 *((unsigned short*)bufferRL++) = rt; *((unsigned short*)bufferRL++) = lt; *((unsigned short*)bufferRL++) = rt; *((unsigned short*)bufferRL++) = lt; *((unsigned short*)bufferRL++) = rt; *((unsigned short*)bufferRL++) = lt; *((unsigned short*)bufferRL++) = rt; *((unsigned short*)bufferRL++) = lt; 44100なら1行分でいい。(これは11025の場合。) ここは別に、(rtがintなら)(int=32bit)(short=16bit) rt<<=16; rt|=lt; *((unsigned long*)bufferRL++) = rt;   (long=32bit) としても、いい筈。ちょっとテストしてみるか。(でも遅くなる気もする) あ、他との兼ね合いがあるから、取りあえず *((unsigned long*)bufferRL) = rt;   (long=32bit) bufferRL++; bufferRL++; いまBufferRLはショート型のポインタ。 ロングにするのなら「ADVANCEPAN」の合成部分も変えないとだめ、と思って めんどいからテストやめよ。(やるなら、もっとずっと後で(ロングになった頃)だな)

■実験的に、76496のUpdateOneと DACと DACのミキサーと サウンドレンダーゼロクリアを外して、 「BF03チェック」をしてみた。 (本当は76496のUpdateOneはダミーで動作させた方が参考になった) 昨日(MUSASI2.XX/GCC4.0.0)「A12」
OFF83fps
5512kHz75~76fps
11025kHz73fps
22050kHz68~69fps
44100kHz60fps

FM以外外す実験(MUSASI2.XX/GCC4.0.0)「A13実験中」 (速くなるに決まってる)
OFF84~85fps+1~2
5512kHz79fps+3~4
11025kHz77fps+4
22050kHz72~73fps+4
44100kHz63~64fps+3~4

これ以上はMIXERは頑張っても無駄という指標が欲しかった。 このうち、76496のUpdateOneは搭載しない訳にはいかないから、1~2fpsは下がるだろう。 しかし、DACはもっと簡単な実装で済ませ、殆ど負荷を0にする事ができるだろう。 つまりMIX関係を最適化した場合。上記より、1~2fps低いのが、理想値という事になる。
この結果で着目して欲しいのがOFFの結果だ。(他は実は予測できる範囲なので、どおでもいい) OFFの実装がタコなのが、ばれてるだろ。 つまり、FM音源ユニット自体のエミュレートが重いのではなく、 PSPはバス転送速度自体がとろいのではないか?(CPUが333でも66バスとかさ) バッファへの0クリアの処理時間と、 バッファへのFM音源のレンダリング処理時間の間に、 酷い差が見られないという事だ。 この結果なら、UpdateOneを全て(76496、FM、DAC)一つにまとめ、 PSPのバッファに直接レンダリングすれば、パフォーマンスが上がる可能性がある。(予測:1~2fps)
そこまで出来たらお魚さんにも、搭載すればよい。(それ以前は弄るだけ無駄)
■いい機会だから、前項。MIXERの実験用に、FMのみなる奴で、「A13からFM以外を外した奴」 「256レンダーのテスト」をしてみた。256レンダーなら320レンダーよりも軽い筈。 但しこのゲームは二画面使う。 ゲームは「OutRun2019」。(横256ドット画面モードのゲームは、 これしか思い浮かばなかった。あ、「デンジャラスシード」があるか) (訂正:「デンジャラスシード」は256モードではないです。(デモのみ256モード)。256モードなら「ヴォルフィード」ですね。) 設定は、44100、VSYNCOFF、Geフル画面。 一面で(MIXER外して)どの程度速度が出るか現状の目安をチェックしてみた。 ルールは、始めのトンネルは計測に入れない。(軽すぎ)下コースを進む。 高架の下まで進んだら終了。
FSKIP0: 32fps程度、30まで落ちる FSKIP1: 45fps程度、40まで落ちる FSKIP2: 52fps程度、46まで落ちる FSKIP3: 55fps程度、49まで落ちる FSKIP4: 55fps程度、52まで落ちる FSKIP5: 56fps程度、55まで落ちる FSKIP6: 57fps程度、56まで落ちる
判ったこと、BGは一画面でも二画面でも、違いはない。 OBJが入ると極端に落ちる。 55fpsを過ぎるとよく判らない。(OBJが入って不安定)
測定結果は「程度」はよく判らんので、「落ちる」を目安にする事にしよう。 が、OBJは出方が不安定で明らかに目安にしかならん。 ソフトの選択を間違えたかもしれんが、こいつは比較的OBJが出ないゲーム。 数字を眺めても意味はないので、グラフにしてみよう。 FSKIP0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@OO FSKIP1@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@OOOOO FSKIP2@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@OOOOOO FSKIP3@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@OOOOOO FSKIP4@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@OOO FSKIP5@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@O FSKIP6@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@O
256レンダーの現状はこんな感じだ。「程度」はFSKIP2,3で多めに出てる。測定誤差だろう。 本来きれいな曲線にならなければ、辻褄が合わない。ので、測定結果に、信頼性がない。 対する「落ちる」はきれいな放物線状になっている。 こちらの方が目安として、信頼性がある。 55fps以上の動作を目指すのなら、CPUやメモリの最適化が必須である事が判る筈。 (註:これはゲームのテストではありません。敢えて44100固定でバスに負荷をかける。PSPのバス負荷のテストです。念の為)