Playdate ハンドヘルドコンソールの CPU は非常に高速に動作しますが、特にデータがキャッシュにない場合のメインメモリへのアクセスは比較的遅いです。この非対称性により、作業データをレジスターに保ち、最も頻繁に実行されるコードを限られた命令キャッシュ内に収めるプログラムは、多くのループを含んでいたり、ブランチミスプリディクトが発生していたとしても、ほぼピークの速度で実行できます。したがって、エミュレーターやシミュレーターなどの高負荷ワークロードを狙う開発者は、レジスター使用を最大化し、コアループを命令キャッシュにぴったり収めることで、遅いメインメモリへのトラフィックを最小化することを優先しなければなりません。

命令キャッシュのフットプリントを縮小するため、著者は -O3 の代わりに -Os でコンパイルすること、大きな switch テーブルを少ないブランチに削減すること、そしてまれにしか使われないオペコードやエッジケースをホットコアの外に隔離することを推奨します。関数に __attribute__((section (``.text.<name>'')) ) を付け、SDK の C_API/buildsupport フォルダーからコピーしたカスタムリンカースクリプトを使用すると、リンカーはすべてのコア関数を単一の連続したブロックに配置でき、そのサイズは nm Source/pdex.elf | sort > syms.txt で調べられます。データについては、ハードウェアスタックが存在するタイトに結合されたメモリ(TCM)領域は通常の RAM よりも高速にアクセスできるため、スタック確保されたオブジェクトはより早く実行され、開発者はヒープまたは静的構造体をスタックの低い領域(dtcm_mempool)に memcpy して計算の期間だけ使用し、結果を元に戻すことができます。同様に、関数は __attribute__((section (``.itcm. '')) ) __attribute__((short_call)) を追加するマクロで命令 TCM(ITCM)領域にマークでき、これは .text から TCM へのランタイムコピーであり、アドレスの 2 での合同性、short_call/long_call 属性への注意、そしてコピー後に命令キャッシュをフラッシュする必要があります。

上記のテクニックを適用しても、ビルドによっては ``performance lottery`` が発生し、見かけ上関係のない変更が速度に大きく予測不能な変動をもたらすことがあります。この現象は2つのハードウェア効果によるものです。1つはキャッシュラインのずれ(32バイトのラインサイズにより、関数の開始アドレスが32の倍数でないと、2つのラインにまたがり、不要な隣接コードを取り込んだり有用なコードをキャッシュから外したりする)です。もう1つはブランチ予測テーブルで、命令アドレスが1024の倍数ずれていると同じ予測エントリを共有し、ミスプリディクトを引き起こすことです。対策として、リンクマップで . = ALIGN(32); . += offset とするか、-falign-loops=32 のようなコンパイラーフラグを使って関数やループを32バイト境界に意図的に揃え、そして既知の良好なビルドに基づいて . = ALIGN(1024); . += n と sprinkling して予測インデックスをデコレレートします。Playdate ではプリフェッチングの効果は限定的ですが、これらのアラインメントテクニックにより、実践的には ``performance lottery`` 効果はほぼ解消されています。