मैं निम्नलिखित सी ++ 2011 कोड है:सी ++ memory_order/जारी
std::atomic<bool> x, y;
std::atomic<int> z;
void f() {
x.store(true, std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_release);
y.store(true, std::memory_order_relaxed);
}
void g() {
while (!y.load(std::memory_order_relaxed)) {}
std::atomic_thread_fence(std::memory_order_acquire);
if (x.load(std::memory_order_relaxed)) ++z;
}
int main() {
x = false;
y = false;
z = 0;
std::thread t1(f);
std::thread t2(g);
t1.join();
t2.join();
assert(z.load() !=0);
return 0;
}
अपने कंप्यूटर वास्तुकला वर्ग में, हम बताया गया है इस कोड में ज़ोर हमेशा सच आता है कि। लेकिन अब इसकी समीक्षा करने के बाद, मैं वास्तव में समझ नहीं पा रहा हूं कि ऐसा क्यों है।
जो मैं जानता हूँ के लिए:
- के बाद यह
- साथ 'memory_order_acquire' ए बाड़ किसी भी लोड है कि अनुमति नहीं दी जाएगी पिछले भंडार निष्पादित करने की अनुमति नहीं दी जाएगी साथ 'memory_order_release' ए बाड़ इससे पहले इसे निष्पादित करने के बाद आता है।
यदि मेरी समझ सही है, तो निम्नलिखित अनुक्रमों का अनुक्रम क्यों नहीं हो सकता है?
- t1 अंदर,
y.store(true, std::memory_order_relaxed);
- t2 पूरी तरह से चलाता है कहा जाता है, और जब 'एक्स' लोड हो रहा है, इसलिए एक इकाई में जेड बढ़ती नहीं एक 'गलत' देखेंगे
- t1 खत्म निष्पादन
- में मुख्य थ्रेड, ज़ोर विफल रहता है क्योंकि z.load() रिटर्न 0
मैं इस 'अधिग्रहण' के अनुरूप है लगता है - 'रिलीज' नियम है, लेकिन, इस सवाल में सबसे अच्छा जवाब में उदाहरण के लिए: Understanding c++11 memory fences जो बहुत है SIMI मेरे मामले में लार, यह संकेत देता है कि मेरे अनुक्रम में चरण 1 की तरह कुछ 'memory_order_release' से पहले नहीं हो सकता है, लेकिन इसके पीछे कारण के लिए विवरण नहीं मिलता है।
मैं इस बारे में बहुत हैरान हूँ, और बहुत खुशी होगी अगर कोई कुछ प्रकाश डाला सकता है पर यह :)
+1। लेकिन सवाल: क्या आप कह रहे हैं कि एक गैर-कैश-सुसंगत वास्तुकला पर, 'memory_order_release'-स्मृति बाड़ भी अन्य प्रोसेसर के कैश अपडेट होने के लिए पर्याप्त नहीं है? – jogojapan
नहीं, मैं कह रहा हूं कि 'memory_order_release' का उपयोग करके कैश-कोहेरेंसी सुनिश्चित करेगा। लेकिन मुझे माफी मांगनी है, मैंने आपका कोड गलत पढ़ा है - मुझे नहीं लगता कि यह दावा कैसे विफल करेगा। यदि y t2 में सत्य है, तो x t2 में सत्य होगा। तो, मान लीजिए कि 't2' लूप अंततः खत्म हो जाता है, फिर 'z' को बढ़ाया जाना चाहिए। उसके लिए माफ़ करना। –
मैं उत्तर अपडेट कर दूंगा। लेकिन ध्यान रखें कि दो "शामिल" यह सुनिश्चित करता है कि मुख्य रूप से जोर देने से पहले दोनों धागे समाप्त हो जाएं। –