2012-11-02 34 views
6

एक चर को 'अस्थिर' के रूप में घोषित करने का मतलब है कि स्मृति चर से सीधे पढ़ने/लिखना, रजिस्टर चर से नहीं। मुझे 'अनुक्रम बिंदु' के बारे में ज्ञान है। लेकिन मैं शीर्षक में उल्लिखित बयान को समझ नहीं पा रहा हूं।एक कंपाइलर अनुक्रम बिंदुओं में अस्थिर चरों तक पहुंच नहीं ले सकता है; इसका क्या मतलब है?

क्या कोई इसे समझा सकता है, और कुछ कोड स्निपेट भी दे सकता है?

+0

अनुक्रम बिंदुओं पर कुछ पृष्ठभूमि यहां दी गई है - http://www.angelikalanger.com/Articles/VSJ/SequencePoints/SequencePoints.html –

+2

इसका मतलब है कि अनुकूलन और निर्देश जनरेशन के दौरान, कोड/निर्देश अन्यथा पुन: व्यवस्थित किए जा सकते हैं , interleaved, आदि अधिक कुशल निष्पादन के लिए, अस्थिर चर का उपयोग करने वाले निर्देश काफी प्रभावित हैं कि वे कैसे प्रभावित हो सकते हैं। – twalberg

उत्तर

0

अस्थिरता का अर्थ है कि आपके चर को आपके प्रोग्राम के बाहर संशोधित किया जा सकता है और यह कि आपके प्रोग्राम के अभिव्यक्ति अनुक्रमों (निर्देशों) में इसे स्थानांतरित करके संकलक इसकी पहुंच को अनुकूलित नहीं कर सकता है। अस्थिर उपयोग का एक अच्छा उदाहरण ओएस टिक है। अस्थिरता ऑप्टिमाइज़र के लिए एक संकेत है कि हम यह नहीं चाहते कि वह अपनी पहुंच को बदल दे: ओएस टिक के उदाहरण में, हम इसे बाद में या जल्द से जल्द इसे पढ़ना नहीं चाहते हैं।/

, एक अस्थिर वस्तु को एक्सेस करना एक वस्तु को संशोधित करने, एक फ़ाइल को संशोधित करने, या एक बुला -

3

यह सब C11 5.1.2.3

कार्यक्रम निष्पादन

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

से पहले अनुक्रम एक असममित, सकर्मक, इस जोड़ी के लिहाज से मूल्यांकन किसी एकल थ्रेड, जो उन के मूल्यांकन के बीच आंशिक आदेश लाती द्वारा निष्पादित के बीच संबंध है। किसी भी दो मूल्यांकन एक को देखते हुए और बी, अगर एक बी से पहले अनुक्रम है, तो एक के निष्पादन बी के निष्पादन के पूर्व में होना चाहिए ...

भाव के मूल्यांकन के बीच एक अनुक्रम बिंदु की उपस्थिति ए और बी का तात्पर्य है कि हर मूल्य गणना और एक के साथ जुड़े पक्ष प्रभाव

/बी के साथ जुड़े हर मूल्य गणना और पक्ष प्रभाव से पहले अनुक्रम है -/

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

/-/

एक अनुरूप क्रियान्वयन पर कम से कम आवश्यकताएँ हैं:

- अस्थिर वस्तुओं के लिए ऐक्सेस सार मशीन के नियमों के अनुसार सख्ती से मूल्यांकन किया जाता है।

यह व्याख्या करने के लिए वास्तव में आसान नहीं है, लेकिन क्या यह मोटे तौर पर सादे अंग्रेजी में इसका मतलब है: के बाद से अस्थिर वस्तुओं की पहुँच एक पक्ष प्रभाव है, संकलक ऐसे पहुंच दूर का अनुकूलन करने के लिए अनुमति नहीं है, न तो यह है उन्हें एक अलग क्रम में अनुक्रमित करने की इजाजत दी गई, जो अन्यथा शायद सीपीयू पर निर्देश कैश/शाखा भविष्यवाणी के साथ बेहतर प्रदर्शन करने के लिए किया जा सकता है, या सिर्फ बेहतर प्रदर्शन क्योंकि कुछ निश्चित मूल्यों को आसानी से कुछ CPU रजिस्टर में संग्रहीत किया गया था।

(C11 मानक भी स्पष्ट रूप से कहा गया है कि अस्थिर वस्तुओं धागा सुरक्षित होने की गारंटी नहीं कर रहे हैं, एक संदर्भ स्विच के बाद एक अस्थिर वस्तु के मूल्य अनिर्दिष्ट व्यवहार है।)

संपादित एक उदाहरण

0 कोड

volatile int x; 
volatile int y; 
volatile int z; 

x=i; 
y=something; 
z=i; 

तो संकलक पुनः आदेश देने के निष्पादन योग्य निर्देश अनुमति नहीं है को देखते हुए

x=i; 
z=i; 
y=something 

क्योंकि y के लिए उपयोग z के लिए उपयोग से पहले अनुक्रम किया जाना चाहिए। सेमी कॉलन में एक अनुक्रम बिंदु है। लेकिन यदि चर अस्थिर नहीं थे, तो कंपाइलर को फिर से ऑर्डर करने के लिए यह ठीक होगा, अगर यह निर्धारित कर सके कि यह प्रोग्राम के नतीजे को प्रभावित नहीं करेगा।

volatile int v = 5; 
int x; 
int y = (x=7), (x+v); 

याद रखें कि अल्पविराम एक दृश्य बिंदु बनाता है:

2

इस जानबूझ काल्पनिक उदाहरण पर विचार करें। इसलिए, असाइनमेंट x+v से पहले पूरा हो जाएगा। इसके अलावा, के बाद से vvolatile है, संकलक कल्पना नहीं कर सकते कि यह बस अपने घोषणा और पहुँच बिंदु के बीच v को संशोधित करने के लिए कोई कोड है, क्योंकि 5 है: संकलक एक अनुदेश उत्पन्न करना होगा करने के लिए v पढ़ें।

हालांकि, यह संकलक के लिए एक महत्वपूर्ण निर्णय छोड़ देता है: जब v को पढ़ना चाहिए? विशेष रूप से, यह x बताए v से पहले पढ़ने के लिए ठीक हो सकता है?

यह वह जगह है जहाँ आपके प्रश्न से बयान में आता है:

एक संकलक कदम नहीं कर सकते हैं अनुक्रम में अस्थिर चर तक पहुँचता अंक

यह स्पष्ट x सौंपने से पहले v पढ़ने से संकलक पर प्रतिबंध लगाता है , क्योंकि ऐसा करने से अल्पविराम ऑपरेटर द्वारा बनाए गए अनुक्रम बिंदु में पहुंच बढ़ जाएगी। इस प्रतिबंध के बिना, संकलक x असाइन करने से पहले या बाद में v पढ़ने के लिए स्वतंत्र होगा।

+0

या इसके बजाय, एक अस्थिर चर को पढ़ने या लिखना एक दुष्प्रभाव है, और संकलक अनुक्रम बिंदुओं पर दुष्प्रभाव नहीं ले सकता है। आपके द्वारा उद्धृत पाठ किसी भी सी मानक से नहीं है। – Lundin

1

सी ++ "अमूर्त मशीन" के संदर्भ में, एक प्रोग्राम को volatile अनुक्रम ("देखने योग्य व्यवहार") के अनुक्रम द्वारा परिभाषित किया गया है, और कुछ भी अनुकूलक द्वारा बदला जा सकता है।

उदाहरण के लिए, यदि आपके पास कई रजिस्टरों के साथ एक सीपीयू है, तो संकलक के लिए ऑब्जेक्ट्स स्टोर करने के लिए यह पूरी तरह से स्वीकार्य है, जब तक उन्हें volatile घोषित नहीं किया जाता है। सीपीयू द्वारा किए गए मेमोरी एक्सेस को देखने वाले किसी को अब प्रोग्राम की हर चीज दिखाई नहीं देगी, लेकिन volatile एक्सेस की गारंटी होगी।

प्रोग्राम को सही ढंग से अनुकूलित किया गया है यदि यह volatile के समान अनुक्रम का उत्पादन करता है, तो एक ही डेटा के साथ एक ही डेटा के साथ उपयोग करता है।

अनुक्रम बिंदुओं की अवधारणा एक और परत पर रहती है - यह सार मशीन के अंदर संचालन के क्रम से संबंधित है। यदि आपके पास दो अनुक्रमों के बीच कोई अनुक्रम बिंदु नहीं है, तो कोई ऑर्डरिंग गारंटी नहीं है, इसलिए x = 0; return x++ + x++; का कोई निर्धारित परिणाम नहीं है।

इन दो अवधारणाओं को एक साथ रखना मुश्किल है, क्योंकि गैर-volatile पहुंच के बारे में बहुत कम गारंटी है। केवल उदाहरण मैं जल्दी से के बारे में सोच सकता है

int *y = ...; 
volatile int *x = ...; 
std::exception up; 

if (*y == 0) 
    throw up; 

return *x; 

होगा *yvolatile नहीं है, यह कहीं भी किसी भी इसे करने के लिए ले जाने के तक पहुँचता है और यहां तक ​​कि उन्हें बाहर का अनुकूलन करने के लिए यदि संभव हो तो पूरी तरह से स्वीकार्य है, लेकिन किसी भी मामले में *x मूल्यांकन किया जा सकता अगर *y == 0

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

  • कोई संबंधित समस्या नहीं^_^