新版FM音源プログラム (21)

STM32F4 シリーズには、「Adaptive real-time accelerator」(ART Accelerator) と称するフラッシュ・メモリ読み出しのためのキャッシュ機構が備えられています。
フラッシュの読み出し幅は 128 ビット (16 バイト) で、フラッシュ上の命令 (I-Code) に対しては 64 ライン分の命令キャッシュが用意されており、プリフェッチされた命令が格納されます。
命令キャッシュ・メモリ容量としては、16 × 64 = 1024 バイトとなり、90 バイト足らずの calc_slot() 関数は全体がキャッシュ・メモリ内におさまります。
フラッシュ上のデータ (D-Code) に対しては 8 ライン分のデータ・キャッシュが用意されています。
サイン波テーブルを SRAM 上に置いて、フラッシュからは命令を読み出すだけの構成に対する測定結果では、フラッシュ・レイテンシが 0 でも 5 でも 2 スロット当たりの実行サイクル数は 44 となり、命令キャッシュがほぼ完璧に作用していることが分かります。
サイン波テーブルをフラッシュ・メモリ上に置いた場合には、フラッシュ・レイテンシが 0 の場合でも実行サイクル数の測定結果は 47 となり、命令のフェッチとデータの読み込みとで何らかの競合が生じているのが推測されます。
フラッシュ・レイテンシが 5 の場合には、実行サイクル数の測定結果は 57 程度となり、レイテンシ 0 の場合との差は約 10 となります。
各スロット・プロパティの初期設定で、各スロットのサイン波テーブルアクセスに対して、なるべくランダムなアドレスを発生するようにして、なるべくデータ・キャッシュが「効かない」ように考慮してあります。
2 スロット分の計算で、約 10 サイクルの差ということは、1 スロット当たり約 5 サイクルということで、これはデータ・キャッシュが有効でない場合のレイテンシ 5 がそのまま現れていると見ることができます。
「stm32f4xx_hal_flash.h」内で定義されているマクロ

   __HAL_FLASH_DATA_CACHE_DISABLE();

を使ってデータ・キャッシュを無効にしてやっても、測定結果は同様に約 57 サイクルとなることで確認できます。
STM32F303 は、CPU は STM32F4 シリーズと同じ Cortex-M4 ですが、キャッシュ機構が簡略化されています。
フラッシュ・メモリは 64 ビット幅 (8 バイト幅) で読み出され、プリフェッチ・バッファとして 64 ビット幅のバッファが 2 本用意されています。
データ (D-Code) キャッシュは省略されているようです。
実行サイクル数の測定結果は、サイン波テーブルを SRAM 上に置いてフラッシュ・レイテンシが 0 の場合 43 サイクル、レイテンシが 2 の場合 46 サイクルとなっています。
フラッシュ・レイテンシにより変化しているので、キャッシュ機構がレイテンシを完全には隠蔽できていないことを示しています。
サイン波テーブルをフラッシュ上に置いた場合、レイテンシ 0 で 46 サイクル、レイテンシ 2 で 55 サイクルとなっています。
その差は 55 - 46 = 9 サイクルで、サイン波テーブル・アクセス 1 回当たりでは 4.5 クロックが追加されていることになります。