2016-10-08 3 views
2

私が(ロックのような)他の手段でvolatileの交換についての質問ではないのです注意してください、私は約volatile自然を求めています - ので、私は、ある意味でvolatileあるいは全くvolatileを「必要ない」を使用します。間接アクセスで揮発性が必要ですか?

1つのスレッドが変数xInt32)にのみ書き込みを行い、もう1つのスレッドがそれを読み込む場合を考えてみましょう。両方の場合のアクセスは直接的です。

キャッシングを避けるには、volatileが必要ですか?

しかしxへのアクセスが間接的であればどのような - 例えばプロパティ経由:

int x; 
int access_x { get { return x; } set { x = value; } } 

だから、両方のスレッドが今だけaccess_x、ないxを使用しています。 xvolatileとマークする必要がありますか?はいの場合は、volatileが不要になったときに間接的に制限がありますか?

更新は:リーダー(なし書き込み)のようなコードを考えてみます。xがキャッシュ内にあり、volatileずにそこにある可能性があるため、第二ifコンパイラで

if (x>10) 
    ... 
// second thread changes `x` 
if (x>10) 
    ... 

は古い値を使用して評価することができ再取得する必要はありません。

if (access_x>10) 
    ... 
// second thread changes `x` 
if (access_x>10) 
    ... 

との私はxためvolatileをスキップしましょう:私の質問は、このような変更についてです。何が起こるか/何が起こることができますか?

+0

一般的に、volatileで始めるのは嫌です。この場合、プロパティは何も変更されません。 – Karolis

+4

プロパティを追加しても、「間接」の読み書きは行われません。これは単に 'x'に関係するコードの部分を変更します。言い換えれば、*プロパティなしの 'x' *の古くなった値を受け取るつもりならば、プロパティゲッターのコードは' x'の失効した値を受け取るでしょう。 – Rob

+0

@Rob、ありがとうございますが、私はあなたの最初の文を理解していません。 'x = 7'と書いてください。これは直接割り当てです。私は 'setFoo()'を呼び出して 'setBar()'を呼び出し、 'setMe()'を呼び出して 'setX()'を呼び出すと、それはプロパティセッターを呼びます。だからなぜあなたは間接的にプロパティを数えないのですか? – astrowalker

答えて

2

xvolatileとマークする必要がありますか?

はい、いいえ(ほとんどが「はい」)。

「はい」と、技術的には保証がありません。コンパイラ(C#とJIT)は、を任意の最適化にすることができます。ただし、最適化ではシングルスレッドで実行されたときのコードの動作は変更されません。明確な最適化の1つは、プロパティセッターとゲッターへの呼び出しを省略し、フィールドに直接アクセスするだけです(つまり、インライン展開)。もちろん、コンパイラは必要な分析を行い、さらに最適化を行うことができます。

"いいえ"実際にはこれは通常問題ではないためです。メソッドでラップされたアクセスでは、C#コンパイラはフィールドを最適化しません。そして、はそうではありません(メソッドがインライン&hellipであっても、保証はありませんが、AFAIKはそのような最適化isn '私はそれが将来のバージョンではないと思います)。残っているのはメモリコヒーレンシーの問題です(他の理由は ハードウェアレベルで実行される最適化を本質的に扱う&hellip、つまり、volatileが使用されています)。

コードがIntel x86互換ハードウェアでのみ実行される限り、そのハードウェアはすべての読み取りと書き込みをvolatileとして扱います。

ただし、他のプラットフォームは異なる場合があります。 ItaniumとARMは、異なるメモリモデルを持つ一般的な例です。

個人的には、私は専門家に書きたいと思っています。保証の欠如にもかかわらず、うまく動作するコードを書くことは、コードがいくつかの不思議な理由のために動作しなくなるということを将来的に見出すことを求めているだけです。

だから、実際には、フィールドをvolatileとマークする必要があります。

もしそうであれば、間接的にいくつかの制限がありますが、もうvolatileは必要ありません。

号このような制限が存在する場合、それが有用であることが立証されなければなりません。実際には、コンパイラの最適化の限界は実際には(間接的に)「間接レベル」にすぎません。しかし、インダイレクションのレベルはハードウェアレベルの最適化を回避するものではなく、コンパイラの最適化の限界さえも厳密に "実践的"です。コンパイラがコードを深く分析することは決して保証されず、任意の深いレベルの呼び出しに対してより積極的な最適化を実行することはありません。


さらに一般的に私の経験則は、並行処理のシナリオでバグから保護するために通常使用されている特定の機能を使用する必要があるかどうかを判断しようとしている場合です。 「この機能が本当に必要なのか、それともコードがなくてもうまくいくのだろうか?

これは、「費用がどれくらいか聞かなければならないのですが、それを買う余裕がないのですか

+0

ありがとう、レコードのために私は作るためにいくつかの汚いトリックを探していなかった、私はより良い理解を持っていたかった。そして、私はキャンプで "安全第一" :-)です。 – astrowalker

関連する問題