2013-02-04 10 views
6

संभव डुप्लिकेट:
Concurrency: Atomic and volatile in C++11 memory modelक्या सी ++ 11 <atomic> संचालन/स्मृति आदेश ताजगी की गारंटी देता है?

सी ++ 11 <atomic> विनिर्देश के साथ

, वहाँ ताजगी के किसी भी गारंटी है? विभिन्न मेमोरी ऑर्डर के वर्णन केवल रीडरिंग के साथ सौदा करते हैं (जहां तक ​​मैंने देखा है)।

विशेष रूप से, इस स्थिति में:

#include <atomic> 

std::atomic<int> cancel_work(0); 

// Thread 1 is executing this function 
void thread1_func() { 

    ... 

    while (cancel_work.load(<some memory order>) == 0) { 
     ...do work... 
    } 
} 


// Thread 2 executes this function 
void thread2_func() { 

    ... 

    cancel_work.store(1, <some memory order>); 

    ... 

} 

धागा 1 और धागा 2 cancel_work को छोड़कर किसी भी अन्य डेटा साझा नहीं करते हैं, तो यह मेरे लिए है कि किसी भी आदेश देने की गारंटी देता है की जरूरत नहीं कर रहे हैं लगता है और std::memory_order_relax दोनों की दुकान के लिए पर्याप्त होता है और भार। लेकिन क्या यह गारंटी देता है कि थ्रेड 1 को कभी भी स्थानीय स्मृति कैश लाइन को मुख्य मेमोरी से रीफ्रेश किए बिना cancel_work का अपडेट दिखाई देगा? यदि नहीं, तो गारंटी देने के लिए न्यूनतम आवश्यक क्या है?

+1

@UmNyobe मेरा कारण पूछने से पहले मुझे यह प्रश्न नहीं मिला क्योंकि यह अस्थिरता के बारे में प्रतीत होता है। जवाब एक डुप्लिकेट है, लेकिन सवाल यह नहीं है क्योंकि यह आपके द्वारा उल्लेख किए गए "परमाणु और अस्थिर" प्रश्न से अलग कुछ ढूंढने वाले लोगों द्वारा पाया जाएगा। – JanKanis

उत्तर

4

ऐसा कुछ भी नहीं है जो गारंटी देगा कि: सब कुछ ऑर्डर करने के बारे में है। यहां तक ​​कि memory_order_seq_cst बस गारंटी देता है कि चीजें एक ही कुल क्रम में होती हैं। सिद्धांत रूप में, कंपाइलर/पुस्तकालय/सीपीयू कार्यक्रम के अंत में cancel_store से प्रत्येक लोड शेड्यूल कर सकता है।

29.3p13 कि

क्रियान्वयन में एक सामान्य बयान समय के लिए उचित समय के भीतर परमाणु भंडार परमाणु भार के लिए दृश्यमान बनाना चाहिए।

लेकिन "उचित समय" का गठन करने पर कोई विनिर्देश नहीं है।

तो: memory_order_relaxed बस ठीक होना चाहिए, लेकिन memory_order_seq_cst कुछ प्लेटफ़ॉर्म पर बेहतर काम कर सकता है, क्योंकि कैश लाइन को जल्द से जल्द पुनः लोड किया जा सकता है।

3

ऐसा लगता है कि this answer भी मेरे प्रश्न का उत्तर देता है। खैर, उम्मीद है कि मेरा प्रश्न googlers को बेहतर खोजने में मदद करेगा।

थ्रेड 1 "उचित समय" में अद्यतन cancel_work देखें, हालांकि उचित रूप से उचित (स्पष्ट रूप से) निर्दिष्ट नहीं है।

2

एक फ़ंक्शन को कॉल करना [जो कि कंपाइलर द्वारा रेखांकित नहीं है] स्वचालित रूप से स्थानीय नहीं होने वाले वेरिएबल वाले किसी भी रजिस्ट्रार को पुनः लोड कर देगा। इसलिए जब तक प्रोजेक्टर thread1_func() को चला रहा है, उसे store के आधार पर कैश-सामग्री फ़्लश या अपडेट किया गया है, यह काम करेगा।

memory_order_relax यह सुनिश्चित करना चाहिए कि डेटा किसी भी अन्य प्रोसेसर कैश से निकला है (यह भविष्य में किसी बिंदु पर) [यह x86 में स्वचालित है, लेकिन सभी प्रकार के प्रोसेसर नहीं हैं, उदाहरण के लिए कुछ एआरएम प्रोसेसर को कोड-संचालित फ्लशिंग की आवश्यकता होती है '], लेकिन यह किसी भी अन्य लेखन [नियमित या परमाणु चर के लिए] से पहले होने की गारंटी नहीं है।

और ध्यान दें कि स्मृति आदेश केवल वर्तमान थ्रेड/प्रोसेसर को प्रभावित करता है। स्टोर या लोड के समय क्या एक और थ्रेड या प्रोसेसर करता है वह पूरी तरह से उस धागे/प्रोसेसर तक होता है।मेरा मतलब यह है कि thread1_func() आपके मामले में 0 मान को पढ़ने के बाद 1 अन्य प्रोसेसर/थ्रेड द्वारा लिखे गए कुछ छोटे समय के लिए मूल्य को पढ़ने में सक्षम हो सकता है। सभी परमाणु संचालन गारंटी यह है कि इसे किसी भी मूल्य को पुराना मान या नया मान मिलता है, जब तक आप memory_order_relax का उपयोग नहीं करते हैं, जो थ्रेड के भीतर संचालन के बीच भार/स्टोर के किसी ऑर्डरिंग को लागू नहीं करता है। हालांकि, जो भी मेमोरी ऑर्डर आप उपयोग कर रहे हैं, परमाणु को गारंटी देना चाहिए [सही कार्यान्वयन मानना] कि मूल्य अंततः अपडेट किया गया है। एक आराम से मामले में कहने के लिए बस मुश्किल है।

संबंधित मुद्दे