コードと変数の配置

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コードは全て同一であり、それぞれ適切な領域に格納されていることを確認しています。

一部抜粋(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

結果

2.png
1.png

1、2番目の比較

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

2、3番目の比較

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

変数

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

一部カードリッジについて

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

お詫び

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

履歴


トップ   一覧 検索 最終更新   ヘルプ   最終更新のRSS