私は次のように単純化できる状況に遭遇したC++コードを最適化しました。gccの最適化は明らかに一定の変数を持つループに影響します
#include <iostream>
#include <thread>
using namespace std;
bool hit = false;
void F()
{
this_thread::sleep_for(chrono::seconds(1));
hit = true;
}
int main()
{
thread t(F);
while (!hit)
;
cout << "finished" << endl;
t.join();
return 0;
}
これは基本的に第二後true
にhit
の値を変化させるスレッドを開始:
、このコードを検討します。同時に、コードはhit
の値がtrue
になるまで続く空のループに入ります。私はgcc-5.4
と-g
フラグを使用してこれを編集し、すべてうまくいきました。コードはfinished
を出力して終了します。しかし、私は-O2
フラグを付けてコンパイルしましたが、今度はコードが無限ループに詰まってしまいました。
解体を見てみると、コンパイラが無限ループの根本的な原因であるとして、次の、生成された:JMP 0x6ba6f3
を! 0x00000000006ba6f3
OK、そうはっきりと、コンパイラはhit
の値がfalse
であると推定していると、それは別のスレッドがその値を変更することが考慮せずに無限ループであることを前提としない、なぜそれがとてもループ内で変更されることはありません!この最適化モードは、上位レベル(-O2
)に追加されています。私は最適化フラグのエキスパートではないので、誰がこの結果を担当しているか教えてもらえますか?それをオフにすると、他のコードに大きなパフォーマンス上のコストがかかりますか?つまり、このコードパターンはどれくらい稀ですか?
は 'std :: atomic'を使用します。 –
Jarod42
ヒットをvolatileと宣言するとどうなりますか? – Milack27
@ Milack27はい、それは問題を解決します!私はまだ分かっていないC++には多くのものがあります! – Sinapse