2013年4月8日月曜日

STM32F1でベンチマーク

久しぶりのエントリ

STM32F1で処理の高速化の実験です

高速化といっても 計算の高速化ではなく
「いかに早くGPIOをバタバタできるか」
という勝負です

なんでこんなことをするかってーと
4096個のパルスを1セットとして
それをどんどん送り続けないとダメなICがあるので
このICは最大30MHzまで受けれるので
ちょっと高速化するくらいでは問題なく受けれます

マイコンはSTBee(STM32F103VE) 動作クロックは72MHzです


エントリーナンバー1番:愚直にforループ
まずは最も遅いと思われるint型のforループ

パルス4096個を送り出すのに必要な時間は
4.034mSec / 1.042MHzでした
1回バタバタするのに70命令くらいでしょうかね
結構使ってるような…

次行きます

エントリーナンバー2番:愚直にforループ(uint16_t版)
0から4096まで数えるだけなので符号はいらないので
intではなくuint16_tにしてみます
これで若干高速化?

と思いきや、実行速度は微妙に落ちてしまいました
4.096mSec
1.031MHzくらい
4096パルスを4.096mSecってキリはいいですが…


エントリーナンバー3番:do - while
forを使わずに do { ... } while (...); はPICで有効な高速化でした

実行時間は3.747mSec/1.124MHz
現時点で最速です


エントリーナンバー4番:GPIO_SetBit
ループの高速化はひとまず終わりとし
別の部分の高速化を図ります
GPIO_WriteBitは内部でif分岐を使用しているため若干処理が遅くなります
ということで 予め設定する値がわかっている場合はSetBitやResetBitを使うことにします

実行時間3.566mSec/1.176MHz
やはりifがない分早くなりました


エントリーナンバー5番:直接制御
SetBitやResetBitで早くなったとはいえ、関数を呼び出す以上オーバーヘッドが発生します
なので、直接レジスタを叩きます

実行時間3.453mSec/1.22MHz
これまた早くなりました


エントリーナンバー6番:ベタ書き
いくら高速化してもループ処理で時間がかかります
ということで繰り返しは直接書いてしまいましょう
4096行書くのは面倒なので 今回は32回の繰り返しを書きます
ループ回数は4096/32で128回です

2.826mSecと大幅に高速化しました

ただしベタ書きをすると
プログラムサイズが大きくなるために、書き込み時間が長くなります
また、ある程度の回数までループ回数が減ると
ベタ書きのメリットが薄くなります

例えば32回では2.826mSecですが 16回では2.841mSecと
ほとんど違いがわかりません
ココはROMサイズと要求時間の兼ね合いで決定されるべきです



以上6種類
高レベル側から低レベル側まで
いくつかの高速化の方法でした