volatile キーワードについて読みましたが、どのような状況で使用すればよいかわかりません。
メモリ(変数)が更新されていて、プロセスがそれを認識していないのはいつですか?
ドライバーはどのような場合に揮発性変数を使用する必要がありますか?
volatile キーワードについて読みましたが、どのような状況で使用すればよいかわかりません。
メモリ(変数)が更新されていて、プロセスがそれを認識していないのはいつですか?
ドライバーはどのような場合に揮発性変数を使用する必要がありますか?
私の世界で最も一般的なケースは、メモリ マップド I/O を使用するマイクロコントローラーをプログラミングする場合です。レジスタの値は外部デジタル入力によって変化する可能性がありますが、変数を として宣言しないvolatile
と、コンパイラがコードを完全に最適化してしまう可能性があり、なぜ何も機能しないのか不思議に思うでしょう。
Matt は、コードが「最適化される」ことに関する声明を装飾することを提案しました。メモリ マップド I/O は、ポインターを介してコードでアクセスされます。ボタンの状態を確認する場合は、通常、レジスタの値とボタンのビットマスクのビット単位の AND を計算します。volatile を指定しない場合、コンパイラは次のように言います。同じ!"。
うまくいけば、これで私の声明が少し明確になります。提案をありがとう、マット。
これをlinux-device-driver
タグでマークしたように、Linux カーネル内でコーディングするための特定のアドバイスが適切である可能性があります。
volatile
通常、 Linux カーネル コードを記述する必要はありません。必要になる可能性がある場合はvolatile
、代わりに呼び出す必要があるコア カーネル関数にラップして使用します。たとえば、メモリ マップド I/O を実行している場合はioremap()
、writel()
、readl()
などを使用する必要があります。
他の人が言ったこととは別に、volatile キーワードは一般に、コンパイラ形式が最適化を行うのを防ぐためのものです。レジスタの値が変化し続ける特定のメモリ マップド レジスタ (RTC クロック レジスタなど) では、volatile キーワードが使用されます。この例を見てください:
RTC_CLOCK _time;
TIME _currentTime = _time ;
while(_currentTime - _time >= 100)
{
//Do something
}
//rest of the code
TIME の前に volatile キーワードを追加しない場合、このコードは _currentTime - _time = 0 のようになり、コンパイラはその下の while ループを考慮しません。
RTC_CLOCK _time;
TIME _currentTime = _time ;
//rest of the code
これを防ぐには、TIME で volatile キーワードを使用する必要があります。
これはあなたに役立つかもしれません
揮発性変数は、プログラムが認識しなくても、いつでも変更できる変数です。
日常のプログラミングで volatile キーワードを使用する方法は思いつきませんが、思いつくかもしれません。
私の知る限り、C では、volatile
同時非同期操作が複数のソース (プロセス) からの変数に対して実行される場合にキーワードを使用する必要があります。変数が宣言されてvolatile
いる場合、マイクロプロセッサのキャッシュに変数をコピーしてそこからアクセスするのではなく、すべてのプロセスが常にそのメモリ位置から変数に直接アクセスします。これにより、その特定の変数のパフォーマンス
が大幅に低下することに注意してください。インメモリ変数のアクセス時間はミリ秒のオーダーですが、第 1 レベルまたは第 2 レベルのキャッシュ変数の場合、約 10 分の 1 ナノ秒です。他のすべてのオプションが考慮された場合にのみ使用してください。