2010-04-18 13 views
64

मैं प्रोजेक्ट में जावा कंसुरेंसी पुस्तक पढ़ रहा हूं। अध्याय 15 में, वे नॉनब्लॉकिंग एल्गोरिदम और तुलना-और-स्वैप (सीएएस) विधि के बारे में बात कर रहे हैं।जावा कंसुरेंसी: सीएएस बनाम लॉकिंग

यह लिखा गया है कि सीएएस लॉकिंग विधियों से काफी बेहतर प्रदर्शन करता है। मैं उन लोगों से पूछना चाहता हूं जो पहले से ही इन दोनों अवधारणाओं के साथ काम करते हैं और जब आप इन अवधारणाओं में से कौन सा पसंद करते हैं तो सुनना चाहते हैं? क्या यह वास्तव में बहुत तेज़ है?

मेरे लिए, ताले के उपयोग (कृपया मुझे सही कर अगर मैं गलत हूँ) ज्यादा स्पष्ट और समझने में अधिक आसान और हो सकता है और भी बेहतर बनाए रखना है। क्या हमें वास्तव में बेहतर प्रदर्शन बढ़ाने के लिए तालाब से सीएएस से संबंधित हमारे समवर्ती कोड बनाने पर ध्यान देना चाहिए या स्थायित्व अधिक महत्वपूर्ण है?

मुझे पता है कि क्या उपयोग करने के लिए शायद सख्त नियम नहीं है। लेकिन मैं सिर्फ सीएएस की नई अवधारणा के साथ कुछ राय, अनुभव सुनना चाहता हूं।

उत्तर

37

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

सीएएस के साथ मुख्य मुद्दा यह है कि लॉकिंग से सही तरीके से प्रोग्राम करना अधिक कठिन होता है। आपको याद है, लॉकिंग, बदले में, संदेश-पासिंग या STM से सही तरीके से उपयोग करना बहुत कठिन है, इसलिए इसे ताले के उपयोग के लिए एक रिंगिंग समर्थन के रूप में न लें।

+0

मैं सहमत हूं कि * एक नए मूल्य की गणना करने के खर्च पर उच्चारण लगाएं *। अक्सर यह इतना बड़ा होता है, जिससे गैर-लॉकिंग रणनीति लॉक-आधारित हो जाती है। –

16

आप एक ConcurrentLinkedQueue और एक BlockingQueue के बीच की संख्या देख सकते हैं। आप क्या देखेंगे कि सीएएस मध्यम (वास्तविक दुनिया अनुप्रयोगों में अधिक यथार्थवादी) थ्रेड अवधारणा के तहत उल्लेखनीय रूप से तेज़ है।

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

अपने प्रश्नों के उत्तर देने के लिए, हाँ थ्रेड सुरक्षित एल्गोरिदम या संग्रह को अनब्लॉक करना (ConcurrentLinkedQueue, ConcurrentSkipListMap/Set) उनके अवरुद्ध समकक्षों के बाद काफी तेज हो सकता है। जैसा कि मार्सेलो ने बताया कि, अनब्लॉकिंग एल्गोरिदम सही हो रहा है, बहुत मुश्किल है और बहुत अधिक विचार की आवश्यकता है।

आपको Michael and Scott Queue के बारे में पढ़ना चाहिए, यह ConcurrentLinkedQueue के लिए कतार कार्यान्वयन है और यह बताता है कि एक सीएएस के साथ दो तरह, थ्रेड सुरक्षित, परमाणु फ़ंक्शन को कैसे संभालना है।

+1

"माइकल और स्कॉट कतार" के बारे में लेख दिलचस्प है। धन्यवाद! – Prine

12

वहाँ अच्छी किताब दृढ़ता से ताला मुक्त संगामिति के विषय से संबंधित है: "मल्टी-प्रोसेसर प्रोग्रामिंग की कला" मौरिस हेर्लिही

+0

इसके अलावा उनकी प्रस्तुति [भाग 1] (http://research.microsoft.com/apps/video/default.aspx?id=168298) और [भाग 2] (http://research.microsoft.com/apps/video /default.aspx?id=169831) बहुत सार्थक हैं। –

23

आपरेशन के सापेक्ष गति से काफी हद तक एक गैर मुद्दा है। लॉक-आधारित और नॉनब्लॉकिंग एल्गोरिदम के बीच स्केलेबिलिटी में अंतर क्या प्रासंगिक है। और यदि आप 1 या 2 कोर सिस्टम पर चल रहे हैं, तो ऐसी चीजों के बारे में सोचना बंद करें।

गैर-अवरोधक एल्गोरिदम आम तौर पर बेहतर होते हैं क्योंकि उनके पास लॉक-आधारित एल्गोरिदम से छोटे "महत्वपूर्ण खंड" होते हैं।

5

यदि आप वास्तविक दुनिया की तुलना की तलाश में हैं, तो यहां एक है। हमारे आवेदन में दो (2) धागे हैं 1) नेटवर्क पैकेट कैप्चर के लिए एक पाठक धागा और 2) एक उपभोक्ता थ्रेड जो पैकेट लेता है, इसकी गणना करता है और आंकड़ों की रिपोर्ट करता है।

थ्रेड # 1 एक्सचेंजों धागा # के साथ एक समय में एक ही पैकेट 2

परिणाम # 1 - एक कस्टम कैस आधारित के रूप में SynchronousQueue, जहां हमारे वर्ग CASSynchronousQueue कहा जाता है एक ही सिद्धांतों का उपयोग विनिमय का उपयोग करता है:

30,766,538 packets in 59.999 seconds :: 500.763Kpps, 1.115Gbps 0 drops 
libpcap statistics: recv=61,251,128, drop=0(0.0%), ifdrop=0 

परिणाम # 2 - जब हम मानक जावा के साथ हमारे कैस कार्यान्वयन की जगह एस ynchronousQueue:

8,782,647 packets in 59.999 seconds :: 142.950Kpps, 324.957Mbps 0 drops 
libpcap statistics: recv=69,955,666, drop=52,369,516(74.9%), ifdrop=0 

मुझे नहीं लगता कि प्रदर्शन में अंतर किसी भी अधिक स्पष्ट नहीं किया जा सका है।

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