वर्तमान "लॉक-फ्री" कार्यान्वयन अधिकांश समय एक ही पैटर्न का पालन करते हैं:
- * कुछ राज्य पढ़ें और इसकी एक प्रतिलिपि बनाएं **
- * कॉपी संशोधित **
- एक इंटरलाक्ड ऑपरेशन करें
- विफल होने पर पुनः प्रयास करें
(* वैकल्पिक: डेटा संरचना / एल्गोरिथ्म पर निर्भर करता है)
अंतिम बिट एक स्पिनक के समान है। वास्तव में, यह एक बुनियादी स्पिनलॉक है । :)
मैं इस पर @nobugz से सहमत हूं: लॉक-फ्री मल्टी-थ्रेडिंग में उपयोग किए जाने वाले इंटरलॉक किए गए संचालन की लागत कैश और मेमोरी-कोहेरेंसी कार्यों पर हावी है जिसे इसे पूरा करना होगा ।
हालांकि आपको "लॉक-फ़्री" डेटा संरचना के साथ जो हासिल होता है वह यह है कि आपके "ताले" बहुत बारीक होते हैं । यह मौका घटाता है कि दो समवर्ती धागे एक ही "लॉक" (मेमोरी लोकेशन) तक पहुंचते हैं।
अधिकांश समय चाल यह है कि आपके पास समर्पित ताले नहीं हैं - इसके बजाय आप किसी सरणी में सभी तत्वों को या किसी लिंक वाली सूची में सभी नोड्स को "स्पिन-लॉक" के रूप में मानते हैं। यदि आपने अपने पिछले पढ़ने के बाद से कोई अपडेट नहीं किया था, तो आप पढ़ते हैं, संशोधित करते हैं और अपडेट करने का प्रयास करते हैं। अगर वहाँ था, तो आप पुनः प्रयास करते हैं।
यह आपकी "लॉकिंग" बनाता है (ओह, सॉरी, नॉन-लॉकिंग :) बहुत ही महीन दाने वाला, बिना अतिरिक्त मेमोरी या संसाधन की आवश्यकता के।
इसे और अधिक बारीक बनाने से वेट की संभावना कम हो जाती है। अतिरिक्त संसाधन आवश्यकताओं को शुरू किए बिना इसे जितना संभव हो उतना बढ़िया बनाया जाना, बहुत अच्छा लगता है, है ना?
हालांकि अधिकांश मज़े सही लोड / स्टोर ऑर्डरिंग सुनिश्चित करने से आ सकते हैं ।
किसी के अंतर्विरोधों के विपरीत, सीपीयू मेमोरी रीड / रिडर करने के लिए स्वतंत्र हैं - वे बहुत स्मार्ट हैं, वैसे: आपके पास एक एकल थ्रेड से इसे देखने में कठिन समय होगा। हालाँकि, जब आप कई कोर पर मल्टी-थ्रेडिंग करना शुरू करते हैं तो आप मुद्दों में भाग लेंगे। आपका अंतर्ज्ञान टूट जाएगा: सिर्फ इसलिए कि एक निर्देश आपके कोड में पहले से है, इसका मतलब यह नहीं है कि यह वास्तव में पहले होगा। सीपीयू निर्देश को आदेश से बाहर कर सकते हैं: और वे विशेष रूप से मेमोरी एक्सेस के निर्देशों के लिए ऐसा करना पसंद करते हैं, मुख्य मेमोरी विलंबता को छिपाने और अपने कैश का बेहतर उपयोग करने के लिए।
अब, यह अंतर्ज्ञान के खिलाफ निश्चित है कि कोड का एक क्रम "टॉप-डाउन" प्रवाह नहीं करता है, इसके बजाय यह चलता है जैसे कि कोई अनुक्रम नहीं था - और "शैतान का खेल का मैदान" कहा जा सकता है। मेरा मानना है कि इस बात का सटीक उत्तर देना उचित है कि क्या लोड / स्टोर री-ऑर्डर होंगे। इसके बजाय, एक हमेशा के संदर्भ में बात करते हैं Mays और mights और डिब्बे और सबसे खराब के लिए तैयार करते हैं। "ओह, हो सकता है कि सीपीयू इस रीड को लिखने से पहले आने के लिए फिर से करे, इसलिए मेमोरी बैरियर को यहीं, इस मौके पर लगाना सबसे अच्छा है।"
मामले इस तथ्य से जटिल हैं कि यहां तक कि ये मेस और मैट्स सीपीयू आर्किटेक्चर में भिन्न हो सकते हैं। उदाहरण के लिए, ऐसा हो सकता है कि एक वास्तुकला में ऐसा न होने की गारंटी हो ।
"लॉक-फ़्री" मल्टी-थ्रेडिंग अधिकार प्राप्त करने के लिए, आपको मेमोरी मॉडल को समझना होगा।
मेमोरी मॉडल प्राप्त करना और सही की गारंटी देना तुच्छ नहीं है, क्योंकि इस कहानी के अनुसार, जिसमें इंटेल और एएमडी ने MFENCE
जेवीएम डेवलपर्स के बीच कुछ हलचल पैदा करने के प्रलेखन के लिए कुछ सुधार किए हैं । जैसा कि यह निकला, डेवलपर्स ने शुरुआत से जिस प्रलेखन पर भरोसा किया था, वह पहले स्थान पर इतना सटीक नहीं था।
.NET में ताले एक अंतर्निहित मेमोरी बैरियर का परिणाम देते हैं, इसलिए आप उनका उपयोग कर रहे हैं (ज्यादातर समय, यही है ... उदाहरण के लिए देखें यह जो डफी - ब्रैड एबर्स - लाज़ इनिशियलाइज़ेशन, लॉक्स, वॉल्वाइल और मेमोरी पर वैन्स मॉरिसन महानता। बाधाओं। :) (उस पृष्ठ पर लिंक का पालन करना सुनिश्चित करें।)
एक अतिरिक्त बोनस के रूप में, आपको .NET मेमोरी मॉडल एक साइड सर्च पर मिल जाएगा । :)
Vance Morrison से एक "पुराना लेकिन गोल्डी" भी है: मल्टीथ्रेडेड ऐप्स के बारे में हर देव को पता होना चाहिए ।
... और निश्चित रूप से, जैसा कि @ उल्लेख किया गया है, जो डफी विषय पर एक निश्चित पढ़ा है।
एक अच्छा एसटीएम ठीक-ठाक लॉकिंग के करीब पहुंच सकता है, जैसा कि यह हो जाता है और संभवतः एक प्रदर्शन प्रदान करेगा जो हाथ से बने कार्यान्वयन के साथ या बराबर है। उनमें से एक है STM.NET से DevLabs परियोजनाओं एमएस की।
यदि आप .NET-केवल zealot नहीं हैं, तो डॉग ली ने JSR-166 में कुछ बेहतरीन काम किया ।
क्लिफ क्लिक में हैश टेबल्स पर एक दिलचस्प जानकारी दी गई है जो लॉक-स्ट्रिपिंग पर निर्भर नहीं करती है - जैसा कि जावा और .NET समवर्ती हैश टेबल करते हैं - और 750 सीपीयू तक अच्छी तरह से स्केल करते हैं।
यदि आप लिनक्स क्षेत्र में उद्यम करने से डरते नहीं हैं, तो निम्नलिखित लेख वर्तमान मेमोरी आर्किटेक्चर के इंटर्न में अधिक अंतर्दृष्टि प्रदान करता है और कैश-लाइन साझाकरण प्रदर्शन को कैसे नष्ट कर सकता है: प्रत्येक प्रोग्रामर को स्मृति के बारे में क्या जानना चाहिए ।
@ ने MPI के बारे में कई टिप्पणियां कीं: मैं पूरी तरह सहमत हूं कि MPI कुछ क्षेत्रों में चमक सकता है। एक MPI आधारित समाधान के बारे में तर्क करना आसान हो सकता है, लागू करने में आसान हो सकता है और एक आधे-बेक्ड लॉकिंग कार्यान्वयन की तुलना में कम त्रुटि-प्रवण हो सकता है जो स्मार्ट होने की कोशिश करता है। (हालांकि यह - विषयगत रूप से - एसटीएम आधारित समाधान के लिए भी सच है।) मैं यह भी शर्त लगाऊंगा कि प्रकाश-वर्ष आसान है जैसे कि एर्लांग में एक सभ्य वितरित एप्लिकेशन को सही ढंग से लिखना आसान है , जैसा कि कई सफल उदाहरण बताते हैं।
MPI, हालांकि इसकी अपनी लागत और अपनी परेशानी है, जब इसे एकल, मल्टी-कोर सिस्टम पर चलाया जा रहा है । उदाहरण के लिए, इरलांग में, प्रक्रिया निर्धारण और संदेश कतारों के सिंक्रनाइज़ेशन के आसपास हल किए जाने वाले मुद्दे हैं ।
इसके अलावा, उनके मूल में, MPI सिस्टम आमतौर पर "लाइटवेट प्रोसेस" के लिए एक प्रकार का सहकारी N: M शेड्यूलिंग लागू करते हैं। उदाहरण के लिए इसका मतलब है कि हल्के प्रक्रियाओं के बीच एक अपरिहार्य संदर्भ स्विच है। यह सच है कि यह "क्लासिक संदर्भ स्विच" नहीं है, लेकिन ज्यादातर उपयोगकर्ता अंतरिक्ष ऑपरेशन है और इसे तेजी से बनाया जा सकता है - हालांकि मुझे पूरी तरह से संदेह है कि इसे 20-200 चक्रों के तहत एक इंटरलॉक किए गए ऑपरेशन में लाया जा सकता है । उपयोगकर्ता-मोड संदर्भ स्विचिंग निश्चित रूप से धीमी हैइंटेल McRT पुस्तकालय में भी। एन: हल्के वजन प्रक्रियाओं के साथ एम समयबद्धन नया नहीं है। एलडब्ल्यूपी लंबे समय से सोलारिस में थे। उन्हें छोड़ दिया गया। NT में फाइबर थे। वे अब एक अवशेष हैं। NetBSD में "सक्रियण" थे। उन्हें छोड़ दिया गया। लिनक्स का N: M थ्रेडिंग के विषय पर अपना खुद का टेक था। लगता है अब तक कुछ मर चुका होगा।
समय-समय पर, नए दावेदार होते हैं: उदाहरण के लिए इंटेल से मैकआरटी , या हाल ही में माइक्रोसॉफ्ट से कॉनक्रैट के साथ उपयोगकर्ता-मोड निर्धारण ।
सबसे निचले स्तर पर, वे वही करते हैं जो N: M MPI शेड्यूलर करता है। Erlang - या कोई भी MPI सिस्टम -, नए UMS का फायदा उठाकर SMP सिस्टम पर बहुत फायदा पहुंचा सकता है ।
मुझे लगता है कि ओपी का प्रश्न किसी भी समाधान के लिए / के खिलाफ / व्यक्तिपरक तर्कों की योग्यता के बारे में नहीं है, लेकिन अगर मुझे इसका जवाब देना है, तो मुझे लगता है कि यह कार्य पर निर्भर करता है: निम्न स्तर के निर्माण के लिए, उच्च प्रदर्शन बुनियादी डेटा संरचनाएं जो एक ईपी पर चलती हैं कई कोर के साथ एकल प्रणाली , या तो कम-लॉक / "लॉक-फ्री" तकनीक या एसटीएम प्रदर्शन के संदर्भ में सर्वोत्तम परिणाम प्राप्त करेगी और संभवतः किसी एमपीआई समाधान को किसी भी समय प्रदर्शन-वार हरा देगी, भले ही उपरोक्त झुर्रियों को इस्त्री किया गया हो। एर्लांग में जैसे।
किसी एक प्रणाली पर चलने वाले मध्यम से अधिक जटिल किसी भी चीज के निर्माण के लिए, मैं शायद क्लासिक मोटे अनाज वाले लॉकिंग का चयन करूंगा या यदि प्रदर्शन बहुत चिंता का विषय है, तो एक एसटीएम।
वितरित प्रणाली के निर्माण के लिए, एक MPI प्रणाली शायद एक प्राकृतिक विकल्प बनाती है।
ध्यान दें कि .NET के लिए MPI कार्यान्वयन भी हैं (हालांकि वे उतना सक्रिय नहीं हैं)।