16

जेएमएम में औपचारिकता इसका सबसे भ्रमित हिस्सा प्रतीत होता है। मेरे पास जेएमएम कारणता के संबंध में कुछ प्रश्न हैं, और समवर्ती कार्यक्रमों में व्यवहार की अनुमति है।जावा मेमोरी मॉडल में इस व्यवहार की अनुमति क्यों है?

जैसा कि मैं समझता हूं, वर्तमान जेएमएम हमेशा कारणता लूप को प्रतिबंधित करता है। (मैं सही हूँ?)

अब, प्रति JSR-133 दस्तावेज़, पृष्ठ 24 के रूप में, Fig.16, हम एक उदाहरण है जहां:

प्रारंभ में

x = y = 0

थ्रेड 1:

r3 = x; 
if (r3 == 0) 
    x = 42; 
r1 = x; 
y = r1; 

थ्रेड 2:

r2 = y; 
x = r2; 

सहजता से, r1 = r2 = r3 = 42 असंभव लगता है। हालांकि, यह केवल इतना संभव नहीं है, बल्कि जेएमएम में 'अनुमति' भी है।

संभावना के लिए, दस्तावेज है जो मैं समझने में विफल से विवरण है:

एक संकलक यह समझ सकते हैं कि केवल मूल्यों कभी x करने के लिए सौंपा 0 और 42 कि से, संकलक कर सकता हैं उस बिंदु को घटाएं, पर जहां हम r1 = x निष्पादित करते हैं, या तो हमने 42 से x का लेखन किया था, या हमने केवल x पढ़ा था और मूल्य 42 देखा था। किसी भी मामले में, यह पढ़ने के लिए कानूनी होगा x मूल्यदेखने के लिए42. फिर यह r1 = x से r1 = 42 बदल सकता है; यह y = r1 को y = 42 में परिवर्तित करने और पहले प्रदर्शन करने की अनुमति देगा, जिसके परिणामस्वरूप प्रश्न में व्यवहार होगा। इस मामले में, y पर लिखें पहले किया गया है।

मेरा प्रश्न है, यह वास्तव में किस तरह का संकलक अनुकूलन है? (मैं कंपाइलर-अज्ञानी हूं।) चूंकि 42 केवल सशर्त रूप से लिखा गया है, जब if कथन संतुष्ट है, तो संकलक x के लेखन के साथ कैसे जा सकता है?

दूसरे, भले ही संकलक यह सट्टा अनुकूलन करता है, और y = 42 और करता है तो अंत में r3 = 42 बनाता है, यह करणीय पाश का उल्लंघन नहीं है, के बाद से वहाँ कोई कारण है और प्रभाव भेद अब छोड़ दिया है?

वास्तव में एक ही दस्तावेज़ (पृष्ठ 15, चित्रा 7) में एक उदाहरण है जहां एक समान कारण लूप को अस्वीकार्य माना जाता है।

तो जेएमएम में यह निष्पादन आदेश कानूनी कैसे है?

उत्तर

6

के रूप में बताया गया है, केवल मान कभी x को पत्र लिखा 0 और 42 थ्रेड 1 हैं:

r3 = x; // here we read either 0 or 42 
if (r3 == 0) 
    x = 42; 
// at this point x is definitely 42 
r1 = x; 

इसलिए JIT कम्पाइलर r1 = 42, और आगे y = 42 रूप r1 = x पुनर्लेखन कर सकते हैं।मुद्दा यह है कि, थ्रेड 1 हमेशा, बिना शर्त 42 से y लिखें। r3 वैरिएबल वास्तव में अनावश्यक है और मशीन कोड से पूरी तरह समाप्त हो सकता है। तो उदाहरण में कोड केवल x से y तक एक कारण तीर की उपस्थिति देता है, लेकिन विस्तृत विश्लेषण से पता चलता है कि वास्तव में कोई कारण नहीं है। आश्चर्यजनक परिणाम यह है कि y को लिखना शुरुआती किया जा सकता है।

अनुकूलन पर एक सामान्य नोट: मैं इसे लेता हूं आप मुख्य स्मृति से पढ़ने में शामिल प्रदर्शन दंड से परिचित हैं। यही कारण है कि जेआईटी कंपाइलर जब भी संभव हो इसे करने से इनकार करने पर झुकता है, और इस उदाहरण में यह पता चला है कि y पर क्या लिखना है, यह जानने के लिए इसे वास्तव में x पढ़ने की आवश्यकता नहीं है।

अंकन पर

एक सामान्य टिप्पणी: r1, r2, r3स्थानीय चर रहे हैं (वे ढेर पर या CPU रजिस्टरों में हो सकता है); x, yसाझा चर (ये मुख्य मेमोरी में हैं)। इसे ध्यान में रखे बिना, उदाहरण समझ में नहीं आएंगे।

1

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

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

3

संकलक कुछ विश्लेषण और अनुकूलन प्रदर्शन कर सकते हैं और Thread1 के लिए कोड का पालन के साथ समाप्त:

y=42; // step 1 
r3=x; // step 2 
x=42; // step 3 

एकल पिरोया निष्पादन के लिए इस कोड को मूल कोड के बराबर है और इसलिए कानूनी है। फिर, यदि थ्रेड 2 का कोड चरण 1 और चरण 2 (जो कि संभव है) के बीच निष्पादित किया गया है, तो r3 को 42 भी असाइन किया गया है।

इस कोड नमूने का पूरा विचार उचित सिंक्रनाइज़ेशन की आवश्यकता को प्रदर्शित करना है।

+0

@Alexei इसमें से कुछ बताते हैं। लेकिन, कंपाइलर को 'r3 = 42' के बजाय' r3 = 0' नहीं बनाना चाहिए? या वे सिर्फ 'एक संभावना' दिखा रहे हैं! – gaganbm

+2

कंपाइलर 'r3 = 42' नहीं बनाता है, यह सिर्फ' r3 = x' बरकरार है। कंपाइलर अनुकूलन हमेशा अधिकतम गहराई में नहीं किया जाता है। यदि न्यूनतम संभावना है कि अनुकूलन शुद्धता का उल्लंघन कर सकता है, तो इसे छोड़ दिया जाता है। दिए गए कोड में, ऐसी कोई परिस्थितियां नहीं हैं, लेकिन अगर कोई अन्य कोड मौजूद है तो वे प्रकट हो सकते हैं। इसके अलावा, संकलक यह तय कर सकता है कि 'r3 = 0'' r3 = x' के समान मूल्य का है। –

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