私はスレッドを扱っていますが、コンパイラが次のコードを最適化する方法について質問があります。
void MyClass::f(){
Parent* p = this->m_parent;
this->m_done = true;
p->function();
}
p
の代わりに関数を呼び出すために (スタック上またはレジスタ内で) を使用することが非常に重要ですthis->m_parent
。クリーンアップ パスを実行するとすぐに別のスレッドから削除される可能性m_done
があるため (これが原因で実際にクラッシュしたことがあります)、その場合、ゴミが含まれている可能性がありますが、スレッド スタック/レジスタはそのままです。true
this
m_parent
GCC/Linux での最初のテストでは、競合状態がないことが示されましたが、これが他のコンパイラにも当てはまるかどうかを知りたいですか?
これはgulp の場合volatile
ですか?私は、「揮発性」が C++ で防止する最適化の種類を調べましたか? このマルチスレッド C++ コードには「揮発性」が必要ですか? しかし、どちらも私の問題に当てはまるとは感じませんでした。
コンパイラがここで何をできるかわからないので、これに頼るのは不安です。次のようなケースが見られます。
- いいえ/有益な最適化。ポインタ
this->m_parent
はスタック/レジスタに格納され、この値は後でこれを呼び出すために使用されますfunction()
。これは望ましい動作です。 - コンパイラーは削除します
p
がthis->m_parent
、たまたまレジスターで既に使用可能であり、コンパイラーはこれを使用して呼び出しを行いますがfunction()
、コンパイラー間では信頼できません。これは、別のプラットフォーム/コンパイラ バージョンに移動するバグを公開する可能性があるため、悪いことです。 - コンパイラはへの呼び出しの前に削除
p
して読み取ります。これにより、私が持つことのできない競合状態が発生します。this->m_parent
function()
ここでコンパイラが許可されていることについて、誰かが光を当てることができますか?
編集
this->m_done
それがであることに言及するのを忘れていましたstd::atomic<bool>
。私はC++ 11を使用しています。