2020年5月2日土曜日

STM32でDCCを作る方向で (9) STM32F2xxの速度はどうかな?

前々回でSPIがDAC IFに使えるかどうかを調べたところ、問題があったけれど原因が判ったので解決の目途が立った.

前回はI2Sを動かしてみて、途切れなくserial audio streamを出力できることを確認した.今日は同じことをSPIに応用してみたところ、I2Sと同様に動いた.しかもSPI1なら最高転送レートが30Mbpsなので32bit384kHz(25Mbps)を通せるので、STM32からのstrem出力はSPI1を採用で決まりだと思う.(SPI1だけである.SPI2SPI3は遅いので192kまで)

今回のお題は、STM32F2xxのCPUの動作はどの程度速いのか? である.

「どうせCPUはボーッとしてるか遊んでるだけじゃん」
「そんなのDMAに勝手にやらせるんだろ?」
と思うのがフツーの人間であろう.

だが、CPUに一肌脱いでもらいたい事があるんだ.
リトルエンディアン → ビッグエンディアン 変換をCPUにやって欲しい.

なぜかというと、USBのFIFOにブタ積みされるaudio data(32bit)はリトルエンディアンらしいのだ.なのにDAC AK4495はビッグエンディアンなのである.

EZ-USBでDCC開発をやっていた頃には、FPGAでリトル→ビッグ変換をやっていた.最低でも32個のFlipFlopを消費するので、できればCPUで変換して欲しいと願う.

STM32F207のCPU clock 120MHz(最高周波数)で動作速度を何種類か試してみた.

まずは、インクリメントの動作速度.
 1)uint32 4000個をincrementする     → 所要時間1mSec
 2)uint16 4000個をincrementする     → 所要時間1mSec
 3)uint8   4000個をincrementする     → 所要時間1.2mSec
4000個を1msでというのは32bit ARMさんは速いもんだね.
uint8だと遅くなっているのはご愛敬w

次は、エンディアン変換の動作速度.codeはCPUさん頑張ってなこんなもの.
uint32_t little2big32(uint32_t little) {
     return ((little & 0xff000000) >> 24)
          + ((little & 0xff0000) >> 8)
          + ((little & 0xff00) << 8)
          + ((little & 0xff) << 24);
}
32bit 4000個のエンディアン変換に要した時間は、2.4mSecだった.

これが十分な動作速度なのかどうか?

サンプリング周波数384kHzなので、1サンプルあたり2.6uSecである.
4000個のaudio dataは、Lch 2000個、Rch 2000個として消費される.
したがって、時間長換算すると5.2mSec分のaudio dataである.

5.2mSec分のaudio dataのエンディアン変換に2.4mSec要する、という結果を得た.
う~ん、CPUロードの約半分がエンディアン変換になるのかぁ、ちょっと気味悪いかな.

以上はSTM32F2xxを120MHz動作させたときの速度だ.もっと速いCPUもあるにはある.例えばSTM32F4xxには180MHzのラインナップがある.単純計算では1.5倍速いと予想される.

エンディアン変換をマシン語で記述したらもっと高速にならないかなぁと思ったりするのだが、コンパイラを舐めるな!という天の声が聞こえる....

今宵はここまでとしとうございます.

追記:10000000*sin(2*3.14*i/1000)の4000回loopに要した時間は約100mSecだった.やっぱ浮動小数点演算は遅い.

かしこ


0 件のコメント:

コメントを投稿