#author("2025-06-05T09:40:00+09:00;2025-06-04T20:23:43+09:00","","")
#author("2025-06-08T07:35:30+09:00;2025-06-04T20:23:43+09:00","","")
* コードと変数の配置 [#lcdae6d1]

ROM, EWRAM, IWRAMにそれぞれ同一のコードを置いた時のベンチマークを以下に表します。内容はVBLANK期間に変数のインクリメントしているだけです。インクリメント変数はs32を使用しており、CPUの1秒間(16,777,216)より小さい(溢れることはない)ということに一応ご留意ください。

 //---------------------------------------------------------------------------
 s32 CodeRom(void)
 {
 	while(*(vu16*)0x4000006 >= 160) {};
 	while(*(vu16*)0x4000006 <  160) {};
 
 	s32 ret = 0;
 
 	while(*(vu16*)0x4000006 >= 160)
 	{
 		ret++;
 	}
 
 	return ret;
 }
 //---------------------------------------------------------------------------
 EWRAM_CODE s32 CodeEwram(void)
 {
 	// 上記の処理と同じ
 }
 //---------------------------------------------------------------------------
 IWRAM_CODE s32 CodeIwram(void)
 {
 	// 上記の処理と同じ
 }

生成されたthumbコードは全て同一であり、それぞれ適切な領域に格納されていることを確認しています。
生成されたthumbコードは全て同じで、それぞれ適切な領域に格納されていることを確認しています。

 一部抜粋(ROM領域)
 
 08000CA4 4A08     ldr     r2,=Lxx_4000006h                        ;9  124
 08000CA6 8813     ldrh    r3,[r2]                                 ;4  128
 08000CA8 2B9F     cmp     r3,9Fh                                  ;2  130
 08000CAA D8FC     bhi     Lxx_8000CA6h                            ;8  138
 08000CAC 4A06     ldr     r2,=Lxx_4000006h                        ;9  147
 08000CAE 8813     ldrh    r3,[r2]                                 ;4  151
 08000CB0 2B9F     cmp     r3,9Fh                                  ;2  153
 08000CB2 D9FC     bls     Lxx_8000CAEh                            ;8  161
 08000CB4 8813     ldrh    r3,[r2]                                 ;4  165
 08000CB6 2000     movs    r0,0h                                   ;2  167
 08000CB8 2B9F     cmp     r3,9Fh                                  ;2  169
 08000CBA D904     bls     Lxx_8000CC6h                            ;8  177
 08000CBC 4A02     ldr     r2,=Lxx_4000006h                        ;9  186
 08000CBE 8813     ldrh    r3,[r2]                                 ;4  190
 08000CC0 3001     adds    r0,1h                                   ;2  192
 08000CC2 2B9F     cmp     r3,9Fh                                  ;2  194
 08000CC4 D8FB     bhi     Lxx_8000CBEh                            ;8  202
 08000CC6 4770     bx      r14                                     ;8  210
 08000CC8 0006     movs    r6,r0                                   ;2  212
 08000CCA 0400     lsls    r0,r0,10h                               ;2  214

* 結果 [#k726e1aa]

#ref(2.png,nolink)
#ref(1.png,nolink)

- 実機:初代GBA、GBA SP、GBA Macroは同じ値になりました。2種類のカードリッジ(EverDrive X5、EZ-FLASH DE)による変化はありません。
| REG_WSCNT | ROM  | EWRAM | IWRAM |
| 0x0000    | 3487 | 4185  | 10463 |
| 0x4317    | 5978 | 4185  | 10464 |
| 0x0317    | 4649 | 4184  | 10463 |

- エミュレータ:mGBA 0.10.5の場合、実機との誤差はあるものの問題になるレベルではないと判断しています。
| REG_WSCNT | ROM  | EWRAM | IWRAM |
| 0x0000    | 3484 | 4180  | 10452 |
| 0x4317    | 5974 | 4181  | 10455 |
| 0x0317    | 4646 | 4181  | 10454 |

** 1、2番目の比較 [#g98850d3]
1番目の「REG_WSCNT = 0x0000」はカードリッジ実行直後の値で、2番目の「REG_WSCNT = 0x4317」は一般的な市販ゲームで使用されている設定値です。ここで理解してほしいことは0x4317 ROMは、0x4317 EWRAMに比べて1.42倍速いことです(5978 / 4185)。また、0x4317 ROMは0x0000 ROMに比べて1.71倍(5978 / 3487)速い、ということもわかります。IWRAMはどちらも非常に高速です。

** 2、3番目の比較 [#o8f622cb]
ROMはプリフェッチ機能がある為、たまたま良いアクセスを引いただけと思われるかもしれません。なので無効化した状態を3番目「REG_WSCNT = 0x0317」に用意しました。プリフェッチをOFFにしてもEWRAMが優位になることはなく(4649 vs 4184)''EWRAMにコードを置くことは選択肢としてないということがわかります''。EWRAMはマルチブート用か、何かROMで動かせない場合に限ります。

** 変数 [#p7ff327a]
変数については以下のように考えてください。リードオンリーな定数はROMか高速なIWRAM、EWRAMは選択外。読んだり書いたりする変数はIWRAMかEWRAMということになります。とりあえずIWRAMに全て投げて、mapファイルを見て考えるというムーブを個人的にしています。

* 一部カードリッジについて [#z97d407e]
supercard sdは0x4317(WS0/ROM=3,1 clks)設定ができない関係で低速になります。この場合、EWRAMにコードを配置することは理にかなっています。

* お詫び [#v3fca7dc]
wikiでは昔からEWRAM_CODEの使用をROMより優位として紹介しており、間違った説明をしていました。申し訳ありませんでした。ドキュメントとチュートリアルは既に修正していますがサンプルプログラムはあまりの数に断念しています。もし仮に読むようなことがある場合は注意のほどお願いいたします。

** 履歴 [#x17f262d]
- 2025/06/04

トップ   差分 履歴 リロード   一覧 検索 最終更新   ヘルプ   最終更新のRSS