एक अनलॉक म्यूटेक्स को लॉक करना कितना कुशल है? म्यूटेक्स की कीमत क्या है?


149

निम्न स्तर की भाषा में (C, C ++ या जो भी हो): मेरे पास म्यूटेक्स का एक गुच्छा होने के बीच विकल्प है (जैसे कि क्या पैथ्रेड मुझे देता है या जो भी देशी सिस्टम लाइब्रेरी प्रदान करता है) या किसी एक वस्तु के लिए एकल।

म्यूटेक्स को लॉक करना कितना कुशल है? यानी कितने कोडांतरक निर्देश होने की संभावना है और उन्हें कितना समय लगता है (म्यूटेक्स अनलॉक होने की स्थिति में)?

म्यूटेक्स की लागत कितनी है? क्या वास्तव में बहुत सारे म्यूटेक्स होना एक समस्या है ? या क्या मैं अपने कोड में केवल म्यूटेक्स चर के रूप में फेंक सकता हूं क्योंकि मेरे पास intचर हैं और यह वास्तव में कोई फर्क नहीं पड़ता?

(मुझे यकीन नहीं है कि विभिन्न हार्डवेयर में कितना अंतर है। अगर वहाँ है, तो मैं उनके बारे में भी जानना चाहूंगा। लेकिन ज्यादातर, मुझे आम हार्डवेयर के बारे में दिलचस्पी है।)

बिंदु यह है कि कई म्यूटेक्स का उपयोग करके, जो प्रत्येक ऑब्जेक्ट के एक एकल म्यूटेक्स के बजाय केवल ऑब्जेक्ट का एक हिस्सा कवर करता है, मैं कई ब्लॉक सुरक्षित कर सकता हूं। और मैं सोच रहा हूं कि मुझे इस बारे में कितनी दूर जाना चाहिए। यानी मुझे किसी भी संभव ब्लॉक को यथासंभव सुरक्षित रखने की कोशिश करनी चाहिए, चाहे कितना भी जटिल हो और कितने अधिक म्यूटेक्स का मतलब हो?


वेबकिट्स ब्लॉग पोस्ट (2016) लॉकिंग के बारे में इस प्रश्न से बहुत संबंधित है, और एक स्पिनलॉक, अनुकूली लॉक, फ़ुटेक्स, आदि के बीच के अंतर को समझाता है।


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

2
@Gian: ठीक है, निश्चित रूप से मैं अपने प्रश्न में इस उपशमन का मतलब है। अगर कोई हो तो मैं सामान्य हार्डवेयर के बारे में जानना चाहता हूं, लेकिन यह भी उल्लेखनीय है।
अल्बर्ट

मैं वास्तव में कहीं भी उस निहितार्थ को नहीं देखता। आप "असेंबलर निर्देशों" के बारे में पूछते हैं - जवाब 1 निर्देश से लेकर दस हजार निर्देशों तक कहीं भी हो सकता है जो इस बात पर निर्भर करता है कि आप किस वास्तुकला की बात कर रहे हैं।
जियान

15
@Gian: तो कृपया इस जवाब बिल्कुल दे। कृपया कहें कि यह वास्तव में x86 और amd64 पर क्या है, कृपया एक आर्किटेक्चर के लिए एक उदाहरण दें जहां यह 1 निर्देश है और एक को वह जगह दें जहां यह 10k है। क्या यह स्पष्ट नहीं है कि मैं अपने प्रश्न से जानना चाहता हूं?
अल्बर्ट

जवाबों:


120

मेरे पास म्यूटेक्स का एक गुच्छा होने या एक वस्तु के लिए एक एकल के बीच विकल्प है।

यदि आपके पास कई धागे हैं और ऑब्जेक्ट तक पहुंच अक्सर होती है, तो कई ताले समानांतरवाद को बढ़ाएंगे। रखरखाव की लागत पर, चूंकि अधिक लॉकिंग का मतलब लॉकिंग का अधिक डिबगिंग है।

म्यूटेक्स को लॉक करना कितना कुशल है? यानी कितना कोडांतरक निर्देश होने की संभावना है और उन्हें कितना समय लगता है (इस मामले में म्यूटेक्स अनलॉक किया गया है)?

सटीक कोडांतरक निर्देश म्यूटेक्स के सबसे कम ओवरहेड हैं - मेमोरी / कैश सुसंगतता मुख्य ओवरहेड हैं। और कम बार एक विशेष ताला लिया जाता है - बेहतर।

म्यूटेक्स दो प्रमुख भागों (ओवरसिम्प्लीफाइंग) से बना है: (1) यह दर्शाता है कि म्यूटेक्स लॉक है या नहीं (2) प्रतीक्षा कतार।

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

अनलॉक किए गए म्यूटेक्स को लॉक करना वास्तव में सस्ता है। Mutex w / o विवाद को खोलना सस्ता भी है।

म्यूटेक्स की लागत कितनी है? क्या वास्तव में बहुत सारे म्यूटेक्स होना एक समस्या है? या मैं अपने कोड में सिर्फ म्यूटेक्स चर के रूप में फेंक सकता हूं क्योंकि मेरे पास अंतर चर हैं और यह वास्तव में कोई फर्क नहीं पड़ता?

आप जितना चाहें उतना म्यूटेक्स वैरिएबल को अपने कोड में फेंक सकते हैं। आप केवल उस मेमोरी की मात्रा तक सीमित हैं, जिसे आप आवेदन कर सकते हैं।

सारांश। उपयोगकर्ता-स्थान लॉक (और विशेष रूप से म्यूटेक्स) सस्ते हैं और किसी भी सिस्टम सीमा के अधीन नहीं हैं। लेकिन उनमें से भी कई डिबगिंग के लिए दुःस्वप्न फैलाते हैं। सरल तालिका:

  1. कम तालों का अर्थ है अधिक सामग्री (धीमी गति से syscalls, CPU स्टॉल) और कम समानता
  2. कम तालों का मतलब बहु-सूत्रण समस्याओं को कम करने वाली कम समस्याएं हैं।
  3. अधिक तालों का अर्थ है कम संतोष और उच्चतर समानता
  4. अधिक तालों का अर्थ है, निर्बाध गतिरोध में चलने की अधिक संभावना।

आवेदन के लिए एक संतुलित लॉकिंग योजना को पाया जाना चाहिए और बनाए रखा जाना चाहिए, आमतौर पर # 2 और # 3 को संतुलित करता है।


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

और स्टॉल हैं जो लॉकिंग कोड को धीरे-धीरे चलाने के लिए बनाता है, अक्सर बिना किसी स्पष्ट संकेत के कि आवेदन धीमा क्यों है। (कुछ आर्क इंटर-सीपीयू / कोर ट्रैफ़िक आँकड़े प्रदान करते हैं, कुछ नहीं।)

समस्या से बचने के लिए, लोग आमतौर पर लॉक सामग्री की संभावना को कम करने और स्टाल से बचने के लिए बड़ी संख्या में तालों का सहारा लेते हैं। यही कारण है कि सस्ते उपयोगकर्ता अंतरिक्ष लॉकिंग, सिस्टम सीमाओं के अधीन नहीं है, मौजूद है।


धन्यवाद, कि ज्यादातर मेरे सवाल का जवाब देता है। मुझे नहीं पता था कि कर्नेल (जैसे लिनक्स कर्नेल) म्यूटेक्स को संभालता है और आप उन्हें syscalls के माध्यम से नियंत्रित करते हैं। लेकिन जैसे ही लिनक्स शेड्यूलिंग और संदर्भ स्विच का प्रबंधन करता है, यह समझ में आता है। लेकिन अब मेरे पास एक मोटा कल्पना है कि म्यूटेक्स लॉक / अनलॉक आंतरिक रूप से क्या करेगा।
अल्बर्ट

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

@ Dummy00001 दूसरी प्रक्रिया में स्विच करने का मतलब है कि आपको सीपीयू की मेमोरी मैपिंग बदलनी होगी। यह इतना सस्ता नहीं है।
जिज्ञासु

27

मैं एक ही बात जानना चाहता था, इसलिए मैंने इसे मापा। मेरे बॉक्स (AMD FX (tm) -8150 E-Core Processor 3.612361 GHz पर), एक अनलॉक किए गए म्यूटेक्स को लॉक और अनलॉक कर रहा है जो कि अपनी कैश लाइन में है और पहले से ही कैश है, 47 घड़ियां (13 एनएस) लेता है।

दो कोर के बीच सिंक्रनाइज़ेशन के कारण (मैंने CPU # 0 और # 1 का उपयोग किया), मैं केवल एक थ्रेड / अनलॉक जोड़ी को दो थ्रेड्स पर हर 102 ns पर कॉल कर सकता था, इसलिए एक बार हर 51 ns, जिसमें से कोई निष्कर्ष निकाल सकता है कि यह लगभग 38 लेता है ns अगले धागे को फिर से लॉक करने से पहले एक थ्रेड को अनलॉक करने के बाद पुनर्प्राप्त करने के लिए।

जिस कार्यक्रम की मैं इसकी जाँच करता था, वह यहाँ पाया जा सकता है: https://github.com/CarloWood/ai-statefultask-testsuite/blob/b69b112e2e91d35b56a39a41809d3de2e9e4b8/src/mutex_test.cxx.cxx

ध्यान दें कि इसमें कुछ हार्डकोड मान हैं जो मेरे बॉक्स के लिए विशिष्ट हैं (xrange, yrange और rdtsc ओवरहेड), इसलिए आपको संभवतः आपके साथ काम करने से पहले इसके साथ प्रयोग करना होगा।

यह उस स्थिति में पैदा होने वाला ग्राफ है:

यहाँ छवि विवरण दर्ज करें

यह निम्नलिखित कोड पर बेंचमार्क रन का परिणाम दिखाता है:

uint64_t do_Ndec(int thread, int loop_count)
{
  uint64_t start;
  uint64_t end;
  int __d0;

  asm volatile ("rdtsc\n\tshl $32, %%rdx\n\tor %%rdx, %0" : "=a" (start) : : "%rdx");
  mutex.lock();
  mutex.unlock();
  asm volatile ("rdtsc\n\tshl $32, %%rdx\n\tor %%rdx, %0" : "=a" (end) : : "%rdx");
  asm volatile ("\n1:\n\tdecl %%ecx\n\tjnz 1b" : "=c" (__d0) : "c" (loop_count - thread) : "cc");
  return end - start;
}

दो rdtsc कॉल घड़ियों की संख्या को मापती हैं, जिन्हें `mutex 'लॉक करना और अनलॉक करना है (मेरे बॉक्स पर rdtsc कॉल के लिए 39 घड़ियों का ओवरहेड)। तीसरा एएसएम एक विलंब लूप है। विलंब लूप का आकार थ्रेड 1 के लिए 1 काउंट छोटा होता है, यह थ्रेड 0 के लिए होता है, इसलिए थ्रेड 1 थोड़ा तेज होता है।

उपरोक्त फ़ंक्शन को 100,000 के तंग लूप में कहा जाता है। इसके बावजूद कि फ़ंक्शन थ्रेड 1 के लिए थोड़ा तेज़ है, दोनों लूप्स म्यूटेक्स को कॉल के कारण सिंक्रनाइज़ करते हैं। यह इस तथ्य से ग्राफ में दिखाई देता है कि लॉक / अनलॉक जोड़ी के लिए मापी गई घड़ियों की संख्या थ्रेड 1 के लिए थोड़ी बड़ी है, इसके नीचे लूप में कम देरी के लिए जिम्मेदार है।

ऊपर के ग्राफ में नीचे दायां बिंदु 150 की देरी लूप_काउंट के साथ एक माप है, और फिर नीचे की ओर बिंदुओं का अनुसरण करते हुए, बाईं ओर, लूप_काउंट प्रत्येक माप द्वारा कम किया जाता है। जब यह 77 हो जाता है तो दोनों थ्रेड्स में हर 102 ns फ़ंक्शन को कहा जाता है। यदि बाद में loop_count कम हो जाता है, तो भी थ्रेड्स को सिंक्रनाइज़ करना संभव नहीं होता है और म्यूटेक्स वास्तव में अधिकांश समय लॉक होना शुरू हो जाता है, जिसके परिणामस्वरूप घड़ियों की एक बढ़ी हुई मात्रा होती है जो लॉक / अनलॉक करने के लिए होती है। साथ ही फ़ंक्शन कॉल का औसत समय इस वजह से बढ़ जाता है; इसलिए भूखंड अंक अब ऊपर और दाईं ओर फिर जाते हैं।

इससे हम यह निष्कर्ष निकाल सकते हैं कि प्रत्येक 50 ns पर एक म्यूटेक्स को लॉक करना और अनलॉक करना मेरे बॉक्स पर कोई समस्या नहीं है।

मेरे सभी निष्कर्षों में यह है कि ओपी के सवाल का जवाब यह है कि अधिक म्यूटेक्स जोड़ना बेहतर है क्योंकि इससे कम विवाद होता है।

जितना हो सके म्यूटेक्स को लॉक करने की कोशिश करें। उन्हें लगाने का एकमात्र कारण -say- एक लूप के बाहर होगा यदि वह लूप हर 100 ns (या बल्कि, उन थ्रेड्स की संख्या जो एक ही समय 50 ns पर उस लूप को चलाना चाहते हैं) की तुलना में या 13 ns से अधिक तेज़ी से होता है लूप का आकार विवाद से आपको मिलने वाली देरी से अधिक देरी है।

संपादित करें: मुझे अब इस विषय पर बहुत अधिक ज्ञान हो गया है और इस निष्कर्ष पर संदेह करना शुरू कर देता हूं कि मैंने यहां प्रस्तुत किया था। सबसे पहले, सीपीयू 0 और 1 हाइपर-थ्रेडेड हो जाते हैं; भले ही AMD 8 असली कोर होने का दावा करता है, लेकिन निश्चित रूप से कुछ बहुत ही गड़बड़ है क्योंकि दो अन्य कोर के बीच देरी बहुत बड़ी है (यानी, 0 और 1 एक जोड़ी बनाते हैं, जैसा कि 2 और 3, 4 और 5, और 6 और 7 करते हैं। )। दूसरे, std :: mutex को इस तरह से लागू किया जाता है कि यह वास्तव में सिस्टम कॉल करने से पहले थोड़ी देर के लिए लॉक कर देता है जब यह म्यूटेक्स पर लॉक को तुरंत प्राप्त करने में विफल रहता है (जिसमें कोई संदेह नहीं है कि यह बहुत धीमी गति से होगा)। तो जो मैंने यहां मापा है वह पूर्ण रूप से आदर्श आदर्श है और लॉकिंग या अनलॉकिंग में प्रति लॉक या अनलॉक में अत्यधिक समय लग सकता है।

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


10

यह उस पर निर्भर करता है जिसे आप वास्तव में "म्यूटेक्स" कहते हैं, ओएस मोड और आदि।

कम से कम यह एक इंटरलॉक्ड मेमोरी ऑपरेशन की लागत है। यह एक अपेक्षाकृत भारी ऑपरेशन है (अन्य आदिम कोडांतरक कमांड की तुलना में)।

हालाँकि, यह बहुत अधिक हो सकता है। यदि आप "म्यूटेक्स" को एक कर्नेल ऑब्जेक्ट कहते हैं (यानी - ओएस द्वारा प्रबंधित वस्तु) और उपयोगकर्ता मोड में चलता है - इस पर प्रत्येक ऑपरेशन एक कर्नेल मोड लेनदेन की ओर जाता है, जो बहुत भारी है।

उदाहरण के लिए इंटेल कोर डुओ प्रोसेसर, विंडोज एक्सपी। इंटरलॉक्ड ऑपरेशन: लगभग 40 सीपीयू चक्र लेता है। कर्नेल मोड कॉल (यानी सिस्टम कॉल) - लगभग 2000 सीपीयू चक्र।

यदि यह मामला है - आप महत्वपूर्ण अनुभागों का उपयोग करने पर विचार कर सकते हैं। यह कर्नेल म्यूटेक्स और इंटरलॉक की गई मेमोरी एक्सेस का हाइब्रिड है।


7
विंडोज महत्वपूर्ण अनुभाग म्यूटेक्स के बहुत करीब हैं। उनके पास नियमित म्यूटिक्स शब्दार्थ हैं, लेकिन वे प्रक्रिया-स्थानीय हैं। अंतिम भाग उन्हें बहुत तेज बनाता है, क्योंकि उन्हें आपकी प्रक्रिया के भीतर पूरी तरह से नियंत्रित किया जा सकता है (और इस प्रकार उपयोगकर्ता-मोड कोड)।
MSalters

2
यदि तुलना के लिए सामान्य कार्यों (जैसे अंकगणित / यदि-और / कैश-मिस / अप्रत्यक्ष) के सीपीयू चक्रों की मात्रा हो तो संख्या अधिक उपयोगी होगी। .... यदि संख्या के कुछ संदर्भ हैं तो यह बहुत अच्छा होगा। इंटरनेट में, ऐसी जानकारी प्राप्त करना बहुत कठिन है।
javaLover

@javaLover ऑपरेशन साइकिल पर नहीं चलते हैं; वे कई चक्रों के लिए अंकगणितीय इकाइयों पर चलते हैं। यह बहुत अलग है। समय में किसी भी निर्देश की लागत एक परिभाषित मात्रा नहीं है, केवल संसाधनों के उपयोग पर लागत। इन संसाधनों को साझा किया जाता है। स्मृति निर्देशों का प्रभाव कैशिंग, आदि पर बहुत अधिक निर्भर करता है
कुरकुरीग्यू

@ क्यूरियस गुय। मैं स्पष्ट नहीं था। मैं उत्तर देना चाहूंगा जैसे कि औसत std::mutexउपयोग की अवधि (दूसरे में) की तुलना में 10 गुना अधिक int++। हालाँकि, मुझे पता है कि इसका उत्तर देना कठिन है क्योंकि यह बहुत हद तक निर्भर करता है।
javaLover

6

कार्यान्वयन के आधार पर लागत अलग-अलग होगी लेकिन आपको दो बातों को ध्यान में रखना चाहिए:

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

एकल प्रोसेसर सिस्टम पर, आप आमतौर पर डेटा को एटमॉली चेंज करने के लिए लंबे समय तक बाधित कर सकते हैं। मल्टी-प्रोसेसर सिस्टम एक परीक्षण-और-सेट रणनीति का उपयोग कर सकते हैं ।

उन दोनों मामलों में, निर्देश अपेक्षाकृत कुशल हैं।

जैसे कि क्या आपको एक विशाल डेटा संरचना के लिए एक म्यूटेक्स प्रदान करना चाहिए, या इसमें से प्रत्येक अनुभाग के लिए कई म्यूटेक्स हैं, यह एक संतुलन कार्य है।

एक एकल म्यूटेक्स होने से, आपके पास कई थ्रेड्स के बीच विवाद का खतरा अधिक होता है। आप प्रति अनुभाग एक म्यूटेक्स होने से इस जोखिम को कम कर सकते हैं, लेकिन आप ऐसी स्थिति में नहीं आना चाहते जहां एक धागा को अपना काम करने के लिए 180 म्यूटेक्स को लॉक करना पड़े :-)


1
हाँ, लेकिन कैसे कुशल? क्या यह एकल मशीन निर्देश है? या लगभग 10? या लगभग 100? 1000? अधिक? यह सब अभी भी कुशल है, हालांकि चरम स्थितियों में फर्क कर सकता है।
अल्बर्ट

1
खैर, यह निर्भर करता है पूरी तरह से कार्यान्वयन पर है। आप इंटरप्ट को बंद कर सकते हैं, एक पूर्णांक को टेस्ट / सेट कर सकते हैं और लगभग छह मशीन निर्देशों में लूप में इंटरप्ट को पुनः सक्रिय कर सकते हैं। टेस्ट-एंड-सेट के बारे में कई किया जा सकता है क्योंकि प्रोसेसर एक निर्देश के रूप में प्रदान करते हैं।
paxdiablo

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

BTW, दूसरों के लिए एक धागा उपज होने के लिए एक साधन के रूप में ड्रॉप / पुनः उपयोग न करें; यह एक रणनीति है जो एक मल्टीकोर सिस्टम पर बेकार है। (यह उन अपेक्षाकृत-कम चीजों में से एक है जो सीपीथॉन गलत हो जाता है।)
डोनल फैलो

@ डॉनल: ड्रॉप / रिक्वायर से क्या मतलब है? यह महत्वपूर्ण लगता है; क्या आप मुझे उस पर अधिक जानकारी दे सकते हैं?
अल्बर्ट

5

मैं pthreads और mutex के लिए पूरी तरह से नया हूं, लेकिन मैं प्रयोग से यह पुष्टि कर सकता हूं कि कोई विवाद नहीं होने पर एक म्यूटेक्स को लॉक / अनलॉक करने की लागत लगभग शून्य है, लेकिन जब विवाद होता है, तो अवरुद्ध करने की लागत बेहद अधिक है। मैंने एक थ्रेड पूल के साथ एक सरल कोड चलाया जिसमें कार्य केवल एक म्यूटेक्स द्वारा संरक्षित वैश्विक चर में एक राशि की गणना करने के लिए था:

y = exp(-j*0.0001);
pthread_mutex_lock(&lock);
x += y ;
pthread_mutex_unlock(&lock);

एक सूत्र के साथ, कार्यक्रम में 10,000,000 मूल्य लगभग तात्कालिक रूप से (एक सेकंड से कम) होते हैं; दो धागे के साथ (4 कोर के साथ मैकबुक पर), एक ही कार्यक्रम में 39 सेकंड लगते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.