GCCがビジーな待機ループを最適化するのを防ぐにはどうしたらよいか?
質問
Atmel AVRマイクロコントローラ用のCコードファームウェアを書きたいと思っています。GCCを使用してコンパイルするつもりです。また、私はコンパイラの最適化を有効にしたいと思います (
-Os
または
-O2
) を有効にしない理由はありませんし、おそらく手動でアセンブリを記述するよりもずっと速く、より良いアセンブリを生成するでしょうから。
しかし、私は最適化されないコードの小さなピースが欲しいのです。私はある関数の実行をある時間だけ遅らせたいので、時間を無駄にするために何もしないループを書きたいと思いました。正確である必要はなく、ただ時間を待つだけです。
/* How to NOT optimize this, while optimizing other code? */
unsigned char i, j;
j = 0;
while(--j) {
i = 0;
while(--i);
}
AVRのメモリアクセスはかなり遅いので、私は
i
と
j
をCPUのレジスタに保持するようにします。
更新: 私はちょうど util/delay.h と util/delay_basic.h です。 から AVR ライブラリ . ほとんどの場合、これらの関数を使用する方が良いアイデアかもしれませんが、この質問は有効で興味深いままです。
関連する質問
- C 言語で gcc がいくつかのステートメントを最適化するのを防ぐには?
- GCC に特定のコードの部分を最適化しないように指示する方法はありますか?
- どのように最適化しないか - 愚直な関数のメカニック
どのように解決するには?
私は、以下のリンクをたどって、この答えを開発しました。 dmckeeの回答 からのリンクをたどって作成したものですが、彼の回答とは異なるアプローチをとっています。
関数の属性 のドキュメントを GCC のメンションから引用しています。
noinline
この関数属性は、関数がインライン化の対象として考慮されないようにします。 関数が副作用を持たない場合、インライン化以外の最適化により、関数呼び出しは生きているにもかかわらず、最適化されなくなることがあります。このような関数呼び出しが最適化されないようにするためにはasm ("");
これは私に面白いアイデアを与えてくれました... を追加する代わりに
nop
命令を追加する代わりに、次のように空のアセンブリコードを追加してみました。
unsigned char i, j;
j = 0;
while(--j) {
i = 0;
while(--i)
asm("");
}
そして、うまくいきました。このループは最適化されておらず、また余分な
nop
命令は挿入されていません。
さらに、もしあなたが
volatile
を使うと、gcc はこれらの変数を RAM に保存し、さらに
ldd
と
std
を使って一時的なレジスタにコピーします。一方、この方法では
volatile
を使用せず、そのようなオーバーヘッドを発生させません。
更新しました。
を使用してコードをコンパイルしている場合
-ansi
または
-std
の場合は
asm
キーワードを
__asm__
のように
GCC ドキュメントに記述されている
.
さらに
__asm__ __volatile__("")
を使うこともできます。
アセンブリ文は置いた場所で実行されなければなりません (つまり、最適化のためにループの外に出してはいけません)。
.
関連
-
error: 'for' loop initial declaration is only allowed in C99 mode 原因と解決方法
-
[解決済み] Linuxカーネルにおけるcontainer_ofマクロの理解
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] C言語では「?」演算子は何をするのですか?
-
[解決済み] C言語で関数をパラメータとして渡すにはどうすればよいですか?
-
[解決済み] C言語標準に準拠した構造体の初期化方法
-
[解決済み] なぜGCCは、速度の代わりにサイズに最適化すると、15-20%速いコードを生成するのですか?
-
[解決済み] gccでC/C++のソースからアセンブラ出力を得るにはどうしたらいいですか?
-
[解決済み】固定長 6 int 配列の最速ソート
-
[解決済み] C言語でgccが一部の文を最適化しないようにするには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
警告:代入がキャストなしで整数からポインタを作成する場合の修正方法に関する警告
-
[解決済み] asm、asm volatile、clobbering memoryの違いについて
-
[解決済み] 初期化でポインタ対象の型から修飾語を捨てる
-
[解決済み] char s[]とchar *sの違いは何ですか?
-
[解決済み] C言語でファイルが存在するかどうかを確認する最も良い方法は何ですか?
-
[解決済み] 講師が書いたC言語のファイルは、なぜ最初の行に#が一つ付いているのですか?
-
[解決済み] C言語で "unsigned long "をprintfする方法は?
-
[解決済み] C言語でgccが一部の文を最適化しないようにするには?
-
[解決済み] C++で文の順序を強制する
-
[解決済み] x86アセンブリの「rep; nop;」とはどういう意味ですか?pause "命令と同じですか?