के साथ लूप पर जीसीसी अनुकूलन प्रभाव मैं एक सी ++ कोड अनुकूलित कर रहा था जिसमें मुझे ऐसी स्थिति का सामना करना पड़ा जिसे निम्नानुसार सरल बनाया जा सकता है।स्पष्ट रूप से निरंतर परिवर्तनीय
इस कोड पर विचार करें:
#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
ध्वज के साथ संकलित किया और इस बार कोड लूप में असीमित रूप से फंस गया।
disassembly को देखते हुए, संकलक निम्नलिखित है, जो अनंत लूप की जड़ है उत्पन्न किया था:
JMP 0x6ba6f3! 0x00000000006ba6f3
ठीक है, तो स्पष्ट रूप से, संकलक निष्कर्ष निकाला गया है कि hit
के मूल्य false
है और यह पाश में परिवर्तन नहीं होगा तो क्यों यह न समझें कि यह एक अनंत लूप है कि एक और धागा अपने मूल्य बदल सकते हैं पर विचार किए बिना ! और यह अनुकूलन मोड उच्च स्तर (-O2
) में जोड़ा जाता है। चूंकि मैं बिल्कुल अनुकूलन ध्वज विशेषज्ञ नहीं हूं, क्या कोई मुझे बता सकता है कि इनमें से कौन सा परिणाम इस परिणाम के लिए ज़िम्मेदार है, इसलिए मैं इसे बंद कर सकता हूं? और इसे बंद करने से कोड के अन्य टुकड़ों के लिए कोई बड़ी प्रदर्शन लागत होगी? मेरा मतलब है, कोड का यह पैटर्न दुर्लभ है?
'std :: atomic' का उपयोग करें। –
Jarod42
क्या होता है यदि आप 'हिट' को अस्थिर घोषित करते हैं? – Milack27
@ मिलैक 27 हां यह समस्या हल करता है! मैन, सी ++ में कई चीजें हैं जिन्हें मैं अभी भी नहीं जानता! – Sinapse