コードと変数の配置

現在工事中・・・。

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

s32 CodeRom(void)
{
	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コードは全て同一となっており目視確認しています。

s32 CodeRom関数(ROM領域)

08000CA4 4A06     ldr     r2,=Lxx_4000006h                        ;9  115
08000CA6 8813     ldrh    r3,[r2]                                 ;4  119
08000CA8 2B9F     cmp     r3,9Fh                                  ;2  121
08000CAA D9FC     bls     Lxx_8000CA6h                            ;8  129
08000CAC 8813     ldrh    r3,[r2]                                 ;4  133
08000CAE 2000     movs    r0,0h                                   ;2  135
08000CB0 2B9F     cmp     r3,9Fh                                  ;2  137
08000CB2 D904     bls     Lxx_8000CBEh                            ;8  145
08000CB4 4A02     ldr     r2,=Lxx_4000006h                        ;9  154
08000CB6 8813     ldrh    r3,[r2]                                 ;4  158
08000CB8 3001     adds    r0,1h                                   ;2  160
08000CBA 2B9F     cmp     r3,9Fh                                  ;2  162
08000CBC D8FB     bhi     Lxx_8000CB6h                            ;8  170
08000CBE 4770     bx      r14                                     ;8  178
08000CC0 0006     movs    r6,r0                                   ;2  180
08000CC2 0400     lsls    r0,r0,10h                               ;2  182

結果

1.png

スクリーンショットはエミュレータ画面ですが、実機(初代GBA、GBA SP)と同じ値です。まず1番目の「REG_WSCNT = 0x0000」についてはカードリッジ実行直後の値で、2番目の「REG_WSCNT = 0x4317」は一般的な市販ゲームで使用されている設定値です。ここで理解してほしいことは0x4317 ROMは、0x4317 EWRAMに比べて1.42倍速いことです(5974 / 4181)。また、0x4317 ROMは0x0000 ROMに比べて1.71倍(5974 / 3484)速い、ということもわかります。IWRAMはどちらも非常に高速です。ROMはプリフェッチ機能がある為、たまたま良いアクセスを引いただけと思われるかもしれません。なので無効化した状態を3番目「REG_WSCNT = 0x0317」に用意しました。プリフェッチをOFFにしてもEWRAMが優位になることはなく(4646 vs 4181)間違ってもEWRAMにコードを置くことのないようお願いします。EWRAMはマルチブート用か、何かROMを動かせない理由がある場合に限ります。

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

お詫び

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

履歴


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