स्मृति आदेश कार्यों पर std::atomic<T>
चर पर पैरामीटर नहीं कि आपरेशन से प्रति के आदेश को प्रभावित करता है, यह आदेश देने के रिश्तों कि आपरेशन अन्य कार्यों के साथ बनाता है प्रभावित करता है।
उदा। a.store(std::memory_order_release)
अपने आप ही आप कैसे a
पर कार्रवाई कुछ और के संबंध में आदेश दिया, लेकिन एक और धागे से a.load(std::memory_order_acquire)
के लिए एक कॉल के साथ जोड़ा जाता है, इस तो अन्य संचालन के आदेश के बारे में कुछ भी नहीं बताता है --- सभी अन्य चर लिखते (सहित गैर-परमाणु वाले) थ्रेड द्वारा किए गए स्टोर को a
पर लोड किया गया था, जो भार लोड किया गया था, अगर वह लोड संग्रहीत मूल्य को पढ़ता है।
आधुनिक प्रोसेसर पर, संचालन पर कुछ स्मृति आदेश नो-ऑप्स नहीं हैं। जैसे x86, memory_order_acquire
, memory_order_consume
और memory_order_release
लोड और स्टोर निर्देशों में निहित हैं, और अलग-अलग बाड़ की आवश्यकता नहीं है। इन मामलों में ऑर्डरिंग संकलक को पुन: निर्देशित करने वाले निर्देश को प्रभावित करती है।
स्पष्टीकरण: दिए गए निर्देशों में निहित बाड़ मतलब हो सकता है कि संकलक किसी भी स्पष्ट बाड़ निर्देश जारी करने के लिए करता है, तो सभी स्मृति आदेश की कमी परमाणु चर पर अलग-अलग संचालन से जुड़े होते हैं की जरूरत नहीं है। यदि आप सबकुछ के लिए memory_order_relaxed
का उपयोग करते हैं, और स्पष्ट बाड़ जोड़ते हैं तो संकलक को उन बाड़ों को निर्देशों के रूप में स्पष्ट रूप से जारी करना पड़ सकता है।
उदा। x86 पर, XCHG
निर्देश इसके साथ एक अंतर्निहित memory_order_seq_cst
बाड़ है। वहाँ इस प्रकार 86 पर नीचे दो विनिमय के संचालन के लिए तैयार किए गए कोड के बीच कोई अंतर नहीं है --- वे एक ही XCHG
अनुदेश के दोनों नक्शा:
std::atomic<int> ai;
ai.exchange(3,std::memory_order_relaxed);
ai.exchange(3,std::memory_order_seq_cst);
हालांकि, मैं अभी तक किसी भी संकलक कि छुटकारा पाने के बारे में पता नहीं कर रहा हूँ निम्नलिखित कोड में स्पष्ट बाड़ निर्देश की:
std::atomic_thread_fence(std::memory_order_seq_cst);
ai.exchange(3,std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_seq_cst);
मैं compilers कि अनुकूलन अंततः संभाल लेंगे उम्मीद है, लेकिन वहाँ अन्य इसी तरह के मामलों में जहां अंतर्निहित बाड़ बेहतर अनुकूलन की अनुमति देगा रहे हैं।
इसके अलावा, std::memory_order_consume
केवल चर पर प्रत्यक्ष संचालन के लिए लागू किया जा सकता है।
हां, मैं इसे समझता हूं, यही मेरा मतलब है * यह स्मृति आदेश केवल उस परमाणु को प्रभावित करता है जिस पर यह कार्य करता है *। दोनों प्रश्न अभी भी खड़े हैं। –
यदि * * परमाणु 'पर मेमोरी ऑर्डर निर्दिष्ट करके * रिश्ते की सिंक्रनाइज़ेशन की गारंटी दी जाती है, और एक बाड़ केवल 'परमाणु ' ऑपरेशन के साथ काम करने की गारंटी है, तो मानक में बाड़ भी क्यों हैं। बस चर पर स्मृति आदेश का उपयोग किसी भी बाड़ की आवश्यकता को रोक देगा। और चूंकि आपको परमाणु के बिना बाड़ का उपयोग करने की अनुमति नहीं है, इसलिए मुझे ऐसी स्थिति दिखाई नहीं दे रही है जहां आप वास्तव में बाड़ चाहते हैं। –
एक सशर्त बाड़ एक ऐसी स्थिति है जहां आप एक स्पष्ट बाड़ का उपयोग करना चाहते हैं। जैसे 'std :: परमाणु पी; अगर (पी.लोड (std :: memory_order_relaxed)) { std :: thread_fence (std :: memory_order_acquire); do_something_with (* पी); } ' या एक स्पिन प्रतीक्षा पाश के बाद: (! P.load (std :: memory_order_relaxed)) ' जबकि { std :: this_thread :: उपज(); } std :: thread_fence (std :: memory_order_acquire); ' –