久しぶりのエントリ
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種類
高レベル側から低レベル側まで
いくつかの高速化の方法でした