- ベストアンサー
volatileについて
マイコンで割り込み(多重あり)を用いたプログラムを作りたいのですが 最適化を利用してできるだけ高速に動作させる必要があります。 多重割り込みを用いるのでvolatile修飾子が必要な変数がたくさんあるのですが 高速動作のためにvolatile修飾が必要な変数のみを厳選したいと思っています。 コンパイラのマニュアルを見ても説明に乏しくどうすればよいか困っています。 例えば割り込み処理終了時にはレジスタの値は変数に戻すなどの規約があればよいのですが・・・。詳しい方は助言をお願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
>このケースにおけるvolatile修飾子は必要なのでしょうか? AとBが多重にならないのでしたら、volatile は不要だと思います。 >コンパイラに割り込み処理AとBの終了時にxの値を変数にストアするという規定がない限り >割り込み処理AとBの変数xを介したインタフェースに問題が生じるはずと思います。 例えば、グローバル変数を変更する他のファイルの関数を呼び出すと、どんな最適化がされていても、戻って来た時点でその変数は確実に変更された値が書き込まれていると思います。 なんらかの特性を利用するか、(もしあれば)#pragma を使うなどしてから、割り込みを終了させればいいのではないかと思います。
その他の回答 (2)
volatile は名前のとおり「揮発する」という意味です。 I/O アクセスを頭に思い浮かべてもらえれば、volatile の意図するところがわかると思います。 レジスタに値が残っていることから変数の再読込が省略されたり、同じ値を2回書き込んでいるので一方が省略されたり、アクセスの順番を勝手に変更したりすることがなくなるということです。 それで、考えなければならない事は2つあると思います。1つは、他の割り込みが「書き込む」可能性のある共通変数には、全て volatile を付けて、常に最新の値を読み込めるようにすること。 もう1つは、例えば共通変数 var があったとして、 var += 2; というような場合に、アセンブリレベルでは、 1. レジスタに var の値をロードする 2. レジスタに 2 を加算する 3. レジスタの値を var にストアする などの数ステップに展開されますが、1 と 2 の間、もしくは 2 と 3 の間で他の割り込み処理によって var の値が変更されても、戻ってきてまた var の値が変更されてしまうので、1~3 を実行中は、他の割り込みがかからないようにするなど、なんらかの安全策を講じる必要があるというところでしょう。 volatile によって、その変数にアクセスしている周辺で最適化が制限されることにはなりますが、深刻に考えるほどではないと思います。アセンブラで作ったとしても必要な無駄でしょうから、アルゴリズムを改善すると割り切った方が健全です。
補足
質問の回答をありがとうございます。 回答の中での2つの考えなければならないことについての特に後者の方は 今まで認識が薄かったため今後プログラミングをする上で十分に注意を払っていきたいと思います。 ところで質問の内容をしぼり再度補足をさせて頂きたいと思います。 例えば2つの割り込み処理ルーチンAとBがあり2つの割り込み処理ルーチンは 共に変数xを書き換えるとします。 プログラム全体でxを書き換えるのは割り込み処理ルーチンのAとBの中のみです。 2つの割り込み処理AとBは交互に発生しますが同一優先順位のため 多重割り込みにはなりません。 コンパイラのマニュアルを見ても 以上の様なケースでは変数xにvolatileをつけるような指示はありませんが もし変数xにvolatile修飾子をつけなければ コンパイラに割り込み処理AとBの終了時にxの値を変数にストアするという規定がない限り 割り込み処理AとBの変数xを介したインタフェースに問題が生じるはずと思います。 このケースにおけるvolatile修飾子は必要なのでしょうか?
- hogeta
- ベストアンサー率14% (4/28)
割り込みを使ったプログラムということですが, まずどのような実行環境と開発環境(せめて対象CPU と使用するコンパイラくらい)を想定している のかを教えてくれないと, アドバイスは難しいと 思います. 組み込み系ソフトウェアなんでしょうかね. 処理を高速化することよりも, 割り込み禁止時間を 短くする方が重要だとは思いますけど.
補足
回答をありがとうございます。 具体的な内容を示します。 組み込みソフトウェアでCPUは日立のSH-1です。コンパイラはSuperH C/C++コンパイラVer7です。 割り込みは全て外部信号からの割り込みで多重割り込み処理を行います。 外部信号の割り込みは複数あるのですがそれを2つに分類して 割り込み優先順位を分けています。 優先順位の高い信号の割り込み処理のみで高速化が必要です。 優先順位の高い信号は2本あり、 この2つの信号の割り込み処理は独立しておらず密接に関係しています。 volatile修飾子をどうするかの判断になやんでいるのは 優先順位の高い2種類の割り込み処理で共通に使用している変数です。 尚これらの変数は優先順位の低い割り込み処理群とは独立しています。
お礼
納得することができました。ありがとうございます。