2011-06-24 16 views
5

हमारे उत्पाद में हमारे पास हार्डवेयर विशिष्ट भागों के लिए विभिन्न प्लेटफ़ॉर्म और कंपाइलर विशिष्ट विधियों का उपयोग करके एक इनलाइन म्यूटेक्स कार्यान्वयन है। "धोखाधड़ी" करने का प्रयास करने वाले कुछ अति-अनुकूलित कोड के लिए हमारे "नियम" में से एक यह है कि यदि एक चर को म्यूटेक्स के अंदर और भीतर पहुंचाया जाता है, तो उस चर को अस्थिर घोषित किया जाना चाहिए। मुझे लगा कि यह अपारदर्शी म्यूटेक्स कार्यान्वयन पर भी लागू होता है (जैसे pthread_mutex_lock/अनलॉक), और इससे एक दिलचस्प बहस हुई।जीसीसी इनलाइन असेंबली के साथ अस्थिर बनाम कंपाइलर बाधा

यह एक व्यक्ति द्वारा जोर दिया गया है कि यह एक कंपाइलर बग का संकेत है (विशेष रूप से जब म्यूटेक्स कार्यान्वयन को संकलक के लिए रेखांकित किया गया है और "अपारदर्शी नहीं है)। मैं इस LinuxPPC जीसीसी कोड टुकड़ा में इस

int v = pSharedMem->myVariable ; 

__asm__ __volatile__(("isync" : : :"memory")) 

v = pSharedMem->myVariable ; 

विवाद के लिए, संकलक isync की रन टाइम प्रभावों का कोई ज्ञान, क्या हम यह स्मृति बाधा के माध्यम से बता सकते हैं के अलावा अन्य नहीं है निम्नलिखित उदाहरण दिया । म्यूटेक्स वास्तव में आयोजित होने से पहले म्यूटक्स के सफल अधिग्रहण का पालन करने वाले निर्देशों के किसी भी निष्पादन को रोकने के लिए आपको एक म्यूटेक्स अधिग्रहण के पूंछ के अंत में ऐसा एक isync निर्देश मिलेगा (इसलिए यदि एक आइसिनक से पहले एक लोड निष्पादित किया गया था त्यागना होगा)।

इस कोड टुकड़ा में, हम संकलक बाधा है कि कोड का एक पुनर्लेखन रोकता है जैसे कि वह निम्नलिखित थे

int v = pSharedMem->myVariable ; 
v = pSharedMem->myVariable ; 

__asm__ __volatile__(("isync" : : :"memory")) 

या

__asm__ __volatile__(("isync" : : :"memory")) 

int v = pSharedMem->myVariable ; 
v = pSharedMem->myVariable ; 

(यानी: इन संकलक फिर दोनों अस्थिरता विशेषता द्वारा 0 अवरुद्ध किया जाना चाहिए)

हमारे पास isync भी है जो पहले पुनर्मूल्यांकन को रोकता है टी रन टाइम (लेकिन मुझे नहीं लगता कि दूसरे को रोकता है जो दिलचस्प नहीं है)।

हालांकि, मेरा सवाल यह है कि यदि मेरा वैरिएबल अस्थिर घोषित किया गया है, चाहे "स्मृति" बाधा पर्याप्त है या नहीं, जीसीसी अनिवार्य रूप से isync के बाद "v" पुनः लोड करेगा? मैं अभी भी इस तरह के पैटर्न के लिए अस्थिर जनादेश के इच्छुक हूं क्योंकि इस तरह के कोड सभी प्लेटफॉर्म विशिष्ट कंपाइलर बिल्टिन के साथ बहुत स्पर्शपूर्ण हैं। उस ने कहा, अगर हम केवल जीसीसी और इस कोड के टुकड़े पर चर्चा को कम करते हैं, तो क्या यह एएसएम मेमोरी बाधा है जो केवल एक के बजाय लोड की एक जोड़ी से उत्पन्न कोड है?

उत्तर

2

"memory" क्लॉबर के साथ पूर्ण रीडरिंग बाधा के रूप में कार्य करने की आवश्यकता है और कार्य करेगा। चर पर volatile अनावश्यक है। वास्तव में यदि आप atomic_t की लिनक्स कर्नेल परिभाषा को देखते हैं, तो यह volatile संशोधक का उपयोग नहीं करता है और उपयुक्त कंक्रीट के साथ __asm__ __volatile__ कथन पर पूरी तरह से निर्भर करता है।

दूसरी ओर, मेरा मानना ​​है कि volatile अपने आप पर वास्तव में पुनर्निर्देशित करने पर रोक लगाता है, केवल मूल्य को पूरी तरह से कैशिंग और अनुकूलित करता है, इसलिए यह सिंक्रनाइज़ेशन उद्देश्यों के लिए बेकार है।

+0

हां, लेकिन मैं परमाणु या ताला शब्द पर अस्थिरता के बारे में बात नहीं कर रहा हूं, लेकिन म्यूटेक्स द्वारा संरक्षित डेटा पर। मैं यह भी नहीं कह रहा हूं कि अस्थिरता में कोई सिंक्रनाइज़ेशन मान है (यानी: सिंक्रनाइज़ेशन म्यूटेक्स द्वारा प्रदान किया जाता है और मैं म्यूटेक्स द्वारा संरक्षित डेटा के बारे में सोच रहा हूं)। यदि म्यूटेक्स के बाहर डेटा भी एक्सेस किया जाता है, तो म्यूटेक्स अधिग्रहित होने के बाद मान को फिर से लोड करने के लिए आवश्यक अस्थिर होता है। –

+0

यहां कुछ अतिरिक्त संदर्भ (मूल चर्चा जो इस प्रश्न को उत्पन्न करती है) http://peeterjoot.wordpress.com/2011/06/21/an-unusual-volatile-required-example/ –

+0

@ पीटर: मैं लगभग निश्चित रूप से नमूना गलत है। कोई भी गैर-रेखांकित फ़ंक्शन कॉल हमेशा स्मृति से गैर-स्थानीय डेटा को पुनः प्राप्त करने के लिए मजबूर करता है, क्योंकि संकलक यह सुनिश्चित नहीं कर सकता कि फ़ंक्शन में उस डेटा के लिए साधारण सूचक नहीं है और बस इसे लिखें, जो सिंगल-थ्रेडेड केस में हो सकता है और वहां अर्थशास्त्र परिभाषित किया गया है। दूसरी ओर यह कोड अस्थिर के साथ या बिना गलत है, क्योंकि कुछ प्लेटफॉर्म पर पढ़ना परमाणु नहीं है। लॉकिंग के बिना साझा चरों तक पहुंचने पर आपको विशेष सिंक्रनाइज़ परमाणु संचालन का उपयोग करने की आवश्यकता है। –

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