2012-01-06 13 views
9

मेरे पास कई प्रक्रियाओं के बीच एक साझा स्मृति है जो स्मृति को एक निश्चित तरीके से इंटरपेट करता है। पूर्व:साझा स्मृति परमाणु पहुंच

DataBlock { 
int counter; 
double value1; 
double ... } 

क्या मैं चाहता हूँ काउंटर के लिए अपडेट करना होगा/atomically वृद्धि की जाती। और उस पते पर एक स्मृति रिलीज होने के लिए। अगर मैं साझा स्मृति का उपयोग कर नहीं थे, उदाहरण के लिए, यह होगा कुछ

तरह
std::atomic<int> counter; 
atomic_store(counter, newvalue, std::memory_order_release); // perform release  operation on the affected memory location making the write visible to other threads 

मैं कैसे एक यादृच्छिक स्मृति स्थान के लिए इस लक्ष्य को हासिल करते हैं (DataBlock काउंटर होने की व्याख्या> ऊपर)। मैं आर्किटेक्चर (x86 linux)

  1. अद्यतन परमाणु - कैसे करें? (यानी atomicupdate (addr, newvalue))
  2. मल्टीकोर के लिए मेमोरी सिंकिंग - (यानी मेमोरीसिंक (एडीआर)) - केवल एक ही तरीका जो मैं देख सकता हूं वह std :: atomic_thread_fence (std :: memory_order_release) का उपयोग कर रहा है - लेकिन यह "स्मृति स्थापित करेगा सभी परमाणु और आराम से परमाणु दुकानों के सिंक्रनाइज़ेशन ऑर्डरिंग "- मेरे लिए ओवरकिल - मैं बस काउंटर स्थान को सिंक्रनाइज़ करना चाहता हूं। किसी भी विचार की सराहना करते हैं।
+3

मैं बस अनुमान लगा रहा हूं, लेकिन मुझे लगता है कि सी ++ प्रोग्रामिंग मॉडल में "प्रक्रियाओं" की कोई धारणा नहीं है और स्मृति मॉडल में "साझा स्मृति" की कोई धारणा नहीं है, इसलिए मुझे संदेह है कि मानक स्वयं ही बनाएगा कोई गारंटी साझा स्मृति बहुत अधिक प्लेटफॉर्म-निर्भर सुविधा है, इसलिए अपने प्लेटफ़ॉर्म के दस्तावेज़ों से परामर्श लें। –

+0

क्या आप अपने डेटाब्लॉक में 'परमाणु ' डाल सकते हैं? इसे तब तक काम करना चाहिए जब तक कि 'परमाणु ' लॉकफ्री है (मानक स्पष्ट उल्लेख स्मृति के बीच प्रक्रियाओं के बीच साझा स्मृति के रूप में साझा किया गया है)। और नहीं, आप केवल एक यादृच्छिक पते के लिए परमाणु नहीं प्राप्त कर सकते हैं (देखें http://stackoverflow.com/questions/8749038/how-to-use-stdatomic- कुशलतापूर्वक/8749474) @ केरेक एसबी: वास्तव में उस परिदृश्य का उल्लेख किया गया है [atomics.lockfree] अंतिम मसौदे में। – Grizzly

+0

@ ग्रीज़ली: आपका मतलब गैर-मानक नोट 29.4/3 है? बहुत दिलचस्प, मुझे यह नहीं पता था। –

उत्तर

-2

आप काउंटर incrementing के लिए लॉक & प्रतीक्षा तंत्र का उपयोग कर सकते हैं। बूस्ट लाइब्रेरी एक लॉक और प्रतीक्षा तंत्र प्रदान करता है। reference

9

के लिए यह लिंक देखें, मैं यहां अधिकार के साथ उत्तर नहीं दे सकता, लेकिन मैं संबंधित जानकारी दे सकता हूं जो मदद कर सकता है।

  1. म्यूटेक्स साझा स्मृति में बनाया जा सकता है और/या क्रॉस-प्रोसेस होने के लिए बनाया जा सकता है। पर्थ्रेड में एक विशेष निर्माण ध्वज है, मुझे याद नहीं है कि क्या वह साझा स्मृति का उपयोग करता है, या फिर आप एक हैंडल साझा करते हैं। लिनक्स "फूटेक्स" सीधे साझा स्मृति का उपयोग कर सकता है (ध्यान दें कि उपयोगकर्ता का पता भिन्न हो सकता है, लेकिन अंतर्निहित वास्तविक पता समान होना चाहिए)

  2. हार्डवेयर परमाणु स्मृति पर काम करते हैं और चर को संसाधित नहीं करते हैं। यही है, आपकी चिप परवाह नहीं करेगा कि कौन से प्रोग्राम चर को संशोधित कर रहे हैं, निम्नतम स्तर पर परमाणु इस प्रकार स्वाभाविक रूप से क्रॉस-प्रोसेस होंगे। वही बाड़ पर लागू होता है।

  3. सी ++ 11 क्रॉस-प्रोसेस परमाणु निर्दिष्ट करने में विफल रहता है। हालांकि, अगर वे लॉक-फ्री हैं (ध्वज की जांच करें) यह देखना मुश्किल है कि एक कंपाइलर उन्हें कैसे कार्यान्वित कर सकता है कि क्रॉस-प्रोसेस काम नहीं करेगा। लेकिन आप अपने टूल-चेन और अंतिम मंच में बहुत अधिक विश्वास रखेंगे।

  4. सीपीयू निर्भरता गारंटी वास्तविक स्मृति पते को भी ट्रैक करती है, इसलिए जब तक आपका प्रोग्राम थ्रेडेड फॉर्म में सही होगा, यह भी इसके बहु-प्रक्रिया फॉर्म (दृश्यता के संबंध में) में सही होना चाहिए।

  5. केरेक सही है, सार मशीन वास्तव में कई प्रक्रियाओं का उल्लेख नहीं करती है। हालांकि, इसके सिंक्रनाइज़ेशन विवरण इस तरह से लिखे गए हैं कि वे बहु-थ्रेड के साथ समान रूप से इंटर-प्रोसेस पर लागू होंगे। यह # 3 से संबंधित है: इसे संकुचित करने के लिए एक कंपाइलर के लिए मुश्किल होगी।

संक्षिप्त उत्तर, ऐसा करने के लिए कोई मानक अनुपालन तरीका नहीं है। हालांकि, मानक मल्टी-थ्रेड्स को परिभाषित करने के तरीके पर झुकाव के साथ आप गुणवत्ता संकलक के लिए कई धारणाएं कर सकते हैं।

सबसे बड़ा सवाल यह है कि क्या परमाणु को साझा स्मृति (प्लेसमेंट नया) और काम में आवंटित किया जा सकता है। जाहिर है यह केवल तभी काम करेगा जब यह एक वास्तविक हार्डवेयर परमाणु है। मेरा अनुमान है कि एक गुणवत्ता कंपाइलर/libary के साथ सी ++ परमाणु साझा साझा स्मृति में काम करना चाहिए।

मज़ेदार व्यवहार व्यवहार करें। :)

4

जब से तुम लिनक्स पर हैं, तो आप gcc परमाणु निर्मित __sync_fetch_and_add()counter के लिए पता पर ... gcc-documentation on atomic built-ins के अनुसार, यह भी एक पूर्ण स्मृति बाड़ को लागू करेगा, न कि रिहाई आपरेशन उपयोग कर सकते हैं, लेकिन चूंकि आप वास्तव में केवल लोड के बजाय एक पठन-संशोधित-लेखन ऑपरेशन चाहते हैं (यानी, काउंटर को बढ़ाने से केवल एक लोड नहीं होता है, लेकिन आपको मूल्य को पढ़ना, फिर संशोधित करना और अंत में लिखना है), पूर्ण- मेमोरी बाड़ इस ऑपरेशन के लिए सही मेमोरी ऑर्डरिंग को लागू करने के लिए एक बेहतर विकल्प होने जा रहा है।

+0

'__sync_fetch_and_add()' का उपयोग किया जा सकता है, लेकिन मुझे लगता है कि '__sync_sub_and_fetch()' अधिक उपयुक्त है। आप संदर्भ गणना को कम करते हैं, और अगर यह शून्य पर चला जाता है तो रिलीज़ करें। यह गारंटी है कि यदि दो थ्रेड एक साथ 2 से कम हो जाते हैं, तो केवल 0 को वापस कर दिया जाएगा (और रिलीज़ होगा)। – ugoren

+0

यह निश्चित रूप से एक अच्छा सुझाव भी है ... एक परमाणु अंतर्निर्मित प्रतियों के दौरान बढ़ने के लिए उपयोग किया जाएगा, और दूसरा जब मूल्य का उपयोग नहीं किया जा रहा है तो मूल्य कम करने के लिए। – Jason

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