2016-09-16 7 views
4

を考えてみましょう:保護されたメンバー変数の間違った共有?

class Vector 
{ 
    double x, y, z; 
    // … 
}; 

class Object 
{ 
    Vector Vec1, Vec2; 
    std::mutex Mtx1, Mtx2; 

    void ModifyVec1() { std::lock_guard Lock(Mtx1); /* … */ } 
    void ModifyVec2() { std::lock_guard Lock(Mtx2); /* … */ } 
}; 

をミューテックスや警備変数が連続して格納され、キャッシュされたとき、彼らはキャッシュラインを共有するいずれかの場合、これは「クロスロック」の一種を引き起こす可能性がありますか?

もしそうなら、それらが保護する変数の直後(またはその前)にmutexを宣言することはよい習慣ですか?

クラスをstd::hardware_destructive_interference_sizeP0154)に設定すると、この影響を避けることができます。オブジェクトのオーバーアライメントに潜在的なメリットはありますか?

+0

C++標準では、クラスメンバーを特定の順序でレイアウトする必要はありません(ここでは適用できない警告があります)。コンパイラのドキュメントから、クラスメンバーに対して決定的な順序を使用するかどうかを判断できます(可能性が高い)。 –

+3

@SamVarshavchik標準レイアウトのクラスでは、宣言の順番でなければならず、今までに投稿された内容に基づいて、これが標準のレイアウトクラスになる可能性があります。また、OPが特定の実装の詳細について質問しているので、それは本当に重要ではありません。 –

+0

@ Rakete1111自由に編集してください。 – metalfox

答えて

3

あなたの変数は、おそらくhardware_constructive_interference_sizeをしたいあなたの質問では無関係なようで、そうではなくhardware_destructive_interference_size

struct keep_together { 
    std::mutex m; 
    Vector v; 
}; 

alignas(std::hardware_constructive_interference_size) keep_together k1; 
alignas(std::hardware_constructive_interference_size) keep_together k2; 

destructiveあなたはロックフリーキューのような場合に使用するには、スレッドは、2つの異なるatomicのを読んでいるだったと両方とも実際にロードされていることを確認する必要があります。それがここで問題になる場合は、なぜあなたが避けているものなのかを説明する必要があります。

同じキャッシュライン上にある可能性を高めるために、変数の直後(またはその前)にmutexを宣言することをお勧めしますか?

つまり、constructiveです。

+0

説明をありがとう。私は両方のコンセプトを混ぜた。私は真の共有を奨励したいと思いますが、起こる可能性がある場合には誤った共有を阻止することもあります。ミューテックスが連続して格納されているとします。彼らはキャッシュラインを共有するだろうか?うまくいけばそれを明確にするために質問を編集しました。 – metalfox

関連する問題