suzukiplan / micro-msx2p

MSX2+ emulator specialized for embedded use
MIT License
10 stars 0 forks source link

性能目標未達(M5Stack) #17

Open suzukiplan opened 1 year ago

suzukiplan commented 1 year ago

性能目標が未達成:

1フレームあたりで換算すると次の通り:

  • 目標: tick 1 frame < 16ms
  • 現状: tick 1 frames = 20.5ms (min:17, max:26)
suzukiplan commented 1 year ago

PSG を削除し、VDP の レンダリング処理をスキップした状態(つまり、ほぼ Z80 だけ動かした状態)にしても約35ms(28/30fps)と目標達成が微妙にできていない。

PSG + VDP レンダリング は 2フレームあたり 6ms 程度(3ms程度)でそろそろ最適化余地が限界に達しつつある。

最適化余地があるとすれば Z80 エミュレーション...と、あとは esp32, FreeRTOS or M5Stack 固有のチューニング余地がある何かだが、それについても万策尽きつつあるかも。

suzukiplan commented 1 year ago

esp32 のマニュアルにパフォーマンスに関する記述がある

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/performance/index.html

上記には「実行速度」「バイナリサイズ」「RAM使用方法」の3つの観点からのアドバイスが書かれている。

実行速度

全体的な速度向上

CONFIG_ESPTOOLPY_FLASHFREQ を80MHzに設定する

これについては既に設定されているっぽい。

https://github.com/suzukiplan/micro-msx2p/pull/23 のログ情報に APB: 80000000 Hz という出力があるので、既に80MHzモードになっている筈。

[    10][D][esp32-hal-cpu.c:244] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz

CONFIG_ESPTOOLPY_FLASHMODEをQIOまたはQOUTモード(Quad I/O)に設定

試しに platformio.ini で、

board_build.flash_mode=qio

を指定してみたが、特段動作速度に変化はなかったので既に設定済みだと思われる。

CONFIG_COMPILER_OPTIMIZATION を Optimize for performance (-O2) に設定

既に非推奨の -O3 相当(-Ofast)で速度が足りてないのですが...

CONFIG_ESP32_REV_MIN を 3 に設定

https://github.com/suzukiplan/micro-msx2p/pull/23 で PSRAM は完全 OFF にしているので関係ない...

浮動小数点演算フロートの使用を避ける

floatdouble も完全排除済み...

倍精度浮動小数点演算倍数の使用を避ける

floatdouble も完全排除済み...

とりあえず全体最適化の余地はもう無い感じっぽい

suzukiplan commented 1 year ago

https://github.com/suzukiplan/micro-msx2p/pull/25 にて大丈夫な感じになった

suzukiplan commented 1 year ago

現状 46〜48fps ぐらいの性能

suzukiplan commented 1 year ago

CoreS3 では 48〜50fps ぐらいの性能(若干程度早くなった)

suzukiplan commented 1 year ago

チャンピオンデータ(56fps)

image

とあるゲーム(グラディウス)のタイトル画面で瞬間的にマークした(あと、なぜがグラディウスは全般的にスコアが良くて、50〜52fpsぐらいを安定的にマークしている)

suzukiplan commented 1 year ago

ゲーム側の実装依存の部分が結構あるかも。

例えば、垂直同期割り込み待ちをする時にJPでぐるぐる回すより、HALTを発行した方がエミュ側の負荷が軽くなりそうです。HALTを発行すると、内部的にはPCのデータを読み捨てる(4Hz ※M1相当だからMSXだと5Hz?)動作をしますがPCがインクリメントされない形になるので、キャッシュミスヒット率が下がりつつ、トータルのネイティブ命令実行数が少なくなるので。

エミュサイドとしては手の入れようが無いなぁ...(垂直同期待ちかどうかを実行コードから動的に判断するのはオーバーヘッドが大きいので、やるならコードをスタティック解析して書き換える感じだが想定外のデグが起こりそうなので原則元コードはエミュ側ではイジらないスタンス)