こんにちは。ojojと申します。プログラム作成中に不明な動きが発生して困っております。
よろしくお願いいたします。
[質問概要] 無限ループした際に、1回目の処理のみ時間が30nsec~50nsec程度遅延します。
[使用マイコン] RX23t
[経緯]
汎用ポートで数10~100nsec単位の信号波形を作る必要があり、無限ループ内でnop()などを使用して信号波形を整形しました。
すると、1ループ目の波形のみ間延びする現象が確認されました。
検証したところ、単純な無限ループでポートHIGH/LOWした時も最初の1ループ目のみ間延びしています。
逆アセンブラなどを見ても処理的には同じところを通っているように見受けられましたので、
どういう処理でこういう現象が起きるのか疑問に思っております。
どなたがご知見のある方がいらっしゃいましたらお教えいただけないでしょうか。
[コード]
#include "r_smc_entry.h"
void main (void){
while(1){ PORT2.PODR.BIT.B2 = 1; PORT2.PODR.BIT.B2 = 0; }}
[コード説明]
P22でひたすらポートをHIGH/LOWしているだけです。開始直後の初回ループのみ、ループに時間がかかります。
わわいです
おそらくは命令キャッシュが効いてるため、と思われます
#実際にRX23tに命令キャッシュが実装されてるかどうかは確認してませんので、そこんとこはデータシートを見ましょう
初回のループの場合は、命令列をフラッシュメモリから内蔵キャッシュメモリに読み込む操作が入ります。
フラッシュメモリのアクセスは、一般的にキャッシュメモリよりはアクセス速度が遅いためにその分時間がかかることになります。
ひとたびそのループ中の命令列がキャッシュに格納されれば、(この程度の命令長であるなら)あとはキャッシュメモリ内のアクセスだけでループが回るため、ノーウェイトで実行することができるようになります
goto 文で試してみたらどうですか
わわい様
ご回答ありがとうございます。
RX23tのデータシートを確認したのですが、キャッシュの記載は確認できませんでした。
キャッシュを意識してデータシートを見たことがないので、見落としがあるかもしれませんが。
リカルド様
goto文でwhile(1)を代替いたしましたが、同様の現象が確認されました。
(初回ループが30nsec程度遅い状態)
> RX23tのデータシートを確認したのですが、キャッシュの記載は確認できませんでした。キャッシュはなくてもパイプラインの記述はありますね。
パイプライン処理は見落としていました。
ループの繰り返し演算が並列処理されて1ループ目以外は高速処理されているということですか。
合点がいきました。ありがとうございます。
信号整形の実処理としては、無限ループの1ループ目では信号生成をせずにスキップする場合分けを設けるとズレが軽減されました。(ループ処理がパイプラインに乗ってから信号生成している形になる?)
イマドキのキャッシュやパイプライン装備のCPU相手では、プログラムループでの一定幅パルス出力生成などは諦めないとしようがないかと思います
パイプライン程度であれば、ループの先頭にパイプラインフラッシュ命令を実行させるとか取れる方法はありますが、命令キャッシュ、データキャッシュ、あまつさえ投機的実行などが絡んでくると、どこでなにが起こってこうなるのか、ってのは追いかけきれません。
ってことで、こういう場合はタイマ出力で実装するようにしましょう