2012-04-01 11 views
24

"उपयोगकर्ता-स्थान" धागे को लागू करने के लिए तैयार कई समाधान हैं। यह golang.org goroutines, पायथन के हरे धागे, सी # एएसआईएनसी, एरलांग की प्रक्रिया आदि हो। विचार यह है कि समवर्ती प्रोग्रामिंग को एक या सीमित संख्या में धागे के साथ भी अनुमति देना है।ओएस धागे महंगा क्यों माना जाता है?

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

ओएस इन दोनों कार्यों को मुफ्त में प्रदान करता है। ओएस थ्रेड "हरे" धागे की तुलना में अधिक महंगा क्यों होना चाहिए? प्रत्येक "कार्य" के लिए समर्पित ओएस थ्रेड होने के कारण अनुमानित प्रदर्शन में गिरावट का कारण क्या है?

+0

वे महंगे नहीं मानते हैं, वे हैं। मेरा मानना ​​है कि कुछ हरे धागे (हास्केल का?) वजन केवल कुछ किलोबाइट वजन है, यानी सौ गुना छोटा है। एक और मुद्दा: मानक पायथन धागे हरे नहीं हैं - जीआईएल के कारण उन्हें बहुप्रचार के साथ कुछ समस्याएं हैं, लेकिन फिर भी वे वास्तविक ओएस धागे हैं (शायद आप 'हरितलेट' के बारे में सोच रहे हैं? ये एक अलग कहानी हैं, और वास्तव में हरे रंग की तरह धागे)। – delnan

+0

@ डेलन ठीक है, मैंने सुना है। लेकिन मुझे अभी भी यकीन नहीं है कि वे और अधिक महंगा क्यों होना चाहिए। दोनों को ढेर को बचाने और संदर्भ स्विच करने की आवश्यकता है (जीआईएल को अनदेखा करें, कई गैर-अजगर उदाहरण हैं)। –

उत्तर

11

मैं ट्यूडर के जवाब में संशोधन करना चाहता हूं जो एक अच्छा प्रारंभिक बिंदु है। धागे के दो मुख्य ओवरहेड हैं:

  1. उन्हें शुरू करना और रोकना। एक ढेर और कर्नेल वस्तुओं को शामिल करने में शामिल है। कर्नेल संक्रमण और वैश्विक कर्नेल ताले शामिल है।
  2. अपने ढेर को चारों ओर रखते हुए।

(1) केवल एक समस्या है यदि आप उन्हें हर समय बना रहे हैं और रोक रहे हैं। यह आमतौर पर थ्रेड पूल का उपयोग कर हल किया जाता है। मैं इस समस्या को व्यावहारिक रूप से हल करने पर विचार करता हूं। थ्रेड पूल पर किसी कार्य को निर्धारित करने में आमतौर पर कर्नेल की यात्रा शामिल नहीं होती है जो इसे बहुत तेज़ बनाता है। ओवरहेड कुछ इंटरलॉक मेमोरी ऑपरेशंस और कुछ आवंटन के क्रम में है।

(2) यह केवल तभी महत्वपूर्ण हो जाता है जब आपके पास धागे (> 100 या तो) हैं। इस मामले में async IO धागे से छुटकारा पाने का माध्यम है। मैंने पाया कि यदि आपके पास अवरुद्ध समेत सिंक्रोनस आईओ की पागल मात्रा नहीं है, तो एसिंक आईओ से थोड़ा तेज़ है (आप इसे सही पढ़ते हैं: सिंक IO तेज़ है)।

+1

(1) मुझे यकीन नहीं है कि क्यों कर्नेल ऑब्जेक्ट उपयोगकर्ता स्पेस ऑब्जेक्ट्स की तुलना में अधिक महंगा है, आपको किसी भी तरह ताले की जरूरत है, और सभी ताले ओएस = कर्नेल लॉक पर उबालते हैं। मुझे समझ में नहीं आता (2) आपको किसी भी तरह अपना ढेर रखना होगा। –

+0

सभी थ्रेड विकल्प स्टैक को चारों ओर नहीं रखते हैं, उदाहरण के लिए जहां भविष्य/कार्य अभी तक निष्पादित करना शुरू नहीं हुआ है। इसके अलावा, ओएस थ्रेड स्टैक अधिक भारी हो सकता है। .NET स्टैक हमेशा 1 एमबी मेमोरी (जो दुर्भाग्यपूर्ण है) प्रतिबद्ध करता है। – usr

+2

के लिए (1): ताले कर्नेल ताले के लिए उबाल नहीं है। बिना शर्त और/या शीघ्र-आयोजित ताले के लिए कई अनुकूलन संभव हैं। कर्नेल ऑब्जेक्ट्स के कई कारणों से अधिक ओवरहेड है (उदाहरण के लिए उन्हें प्रक्रियाओं में साझा किया जा सकता है, एसीएल हो सकता है ...)। उन्हें कर्नेल मोड संक्रमण की भी आवश्यकता होती है। – usr

4

प्रत्येक छोटे कार्य के लिए कर्नेल धागे शुरू करने में समस्या यह है कि यह शुरू करने और रोकने के लिए एक गैर-नगण्य ओवरहेड को घुमाता है, जिसमें स्टैक आकार की आवश्यकता होती है।

यह पहला महत्वपूर्ण बिंदु है: थ्रेड पूल मौजूद हैं ताकि आप उन्हें शुरू करने में समय बर्बाद करने के साथ-साथ अपने ढेर के लिए स्मृति बर्बाद करने से बचने के लिए थ्रेड रीसायकल कर सकें।

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

एक चीज जो कर्नेल धागे की तुलना में "हरे" थ्रेड को तेज़ बनाता है वह यह है कि वे वर्चुअल मशीन द्वारा प्रबंधित उपयोगकर्ता-स्पेस ऑब्जेक्ट्स हैं। उन्हें शुरू करना एक उपयोगकर्ता स्पेस कॉल है, जबकि थ्रेड शुरू करना एक कर्नेल-स्पेस कॉल है जो बहुत धीमा है।

+0

मुझे समझ में नहीं आता कि यह अधिक ओवरहेड क्यों है। यह "हरे" धागे से अलग कैसे है। आपको अपना ढेर रखना है, इसलिए आप एक ही मात्रा में स्मृति बर्बाद कर रहे हैं। –

+1

@ ची-लैन: एक "हरा" धागा वास्तविक धागा नहीं हो सकता है, लेकिन धागे का एक अमूर्त हो सकता है। कुशल उपयोग के लिए कई हरे धागे बुद्धिमानी से उसी कर्नेल थ्रेड पर निर्धारित किए जा सकते हैं, उदाहरण के लिए सहकारी शेड्यूलिंग करने के लिए विंडोज फाइबर का उपयोग करना। – Tudor

+0

@ ची-लैन: इस समस्या से बचने के लिए "हरा"/"हल्के वजन" धागे बनाए जाते हैं। इनमें से उदाहरण हैं हास्केल, एरलांग और पायथन में हैं। –

0

मुझे लगता है कि दो चीजें विभिन्न स्तरों पर हैं।

Thread या Process प्रोग्राम का एक उदाहरण है जिसे निष्पादित किया जा रहा है। एक प्रक्रिया/धागे में इसमें और भी चीजें हैं। निष्पादन ढेर, फाइलें खोलने, सिग्नल, प्रोसेसर की स्थिति, और कई अन्य चीजें।

Greentlet अलग है, यह वीएम में चलाया जाता है। यह एक हल्के वजन धागे की आपूर्ति करता है।उनमें से कई एक छद्म-समवर्ती रूप से आपूर्ति करते हैं (आमतौर पर एक या कुछ ओएस-स्तर धागे में)। और अक्सर वे डेटा साझाकरण के बजाय डेटा-ट्रांसमिशन द्वारा लॉक-फ्री विधि प्रदान करते हैं।

तो, दोनों चीजें अलग-अलग हैं, इसलिए वजन अलग है।

और मेरे दिमाग में, हरे रंग को ओएम में वीएम में समाप्त नहीं किया जाना चाहिए।

+1

वीएम के बिना ग्रीनलेट संभव है, golang.org देखें –

6

"उपयोगकर्ता-स्थान" धागे को लागू करने के लिए कई समाधान तैयार किए गए हैं। यह golang.org goroutines, पायथन के हरे धागे, सी # एएसआईएनसी, एरलांग की प्रक्रिया आदि हो। विचार यह है कि समवर्ती प्रोग्रामिंग को एक या सीमित संख्या में धागे के साथ भी अनुमति देना है।

यह एक अमूर्त परत है। कई लोगों के लिए इस अवधारणा को समझना और कई परिदृश्यों में इसे अधिक प्रभावी ढंग से उपयोग करना आसान है। कई मशीनों (एक अच्छा अमूर्त मानते हुए) के लिए यह भी आसान है, क्योंकि मॉडल कई मामलों में चौड़ाई से खींचने के लिए चलता है। Pthreads के साथ (एक उदाहरण के रूप में), आप सभी नियंत्रण है। अन्य थ्रेडिंग मॉडल के साथ, विचार सस्ता होने के लिए एक समवर्ती कार्य बनाने की प्रक्रिया के लिए, और एक पूरी तरह से अलग थ्रेडिंग मॉडल का उपयोग करने के लिए धागे का पुन: उपयोग करना है। इस मॉडल को पचाना कहीं आसान है; सीखने और मापने के लिए कम है, और परिणाम आम तौर पर अच्छे होते हैं।

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

धागा बनाना महंगा है, और ढेर को स्मृति की आवश्यकता होती है। साथ ही, यदि आपकी प्रक्रिया कई धागे का उपयोग कर रही है, तो संदर्भ स्विचिंग प्रदर्शन को मार सकती है। तो हल्के थ्रेडिंग मॉडल कई कारणों से उपयोगी हो गए। ओएस थ्रेड बनाना मध्यम से बड़े कार्यों के लिए आदर्श रूप से कम संख्या में एक अच्छा समाधान बन गया। यह प्रतिबंधित है, और बनाए रखने के लिए काफी समय ले रहा है।

एक कार्य/थ्रेड पूल/उपयोगकर्तालैंड थ्रेड को संदर्भ स्विचिंग या थ्रेड निर्माण के बारे में चिंता करने की आवश्यकता नहीं है। यह अक्सर उपलब्ध होने पर संसाधन का पुन: उपयोग करता है, अगर यह अब तैयार नहीं है - यह भी, इस मशीन के लिए सक्रिय धागे की संख्या निर्धारित करें "।

अधिक आम तौर पर (आईएमओ), ओएस स्तर धागे महंगी हैं क्योंकि इन्हें इंजीनियरों द्वारा सही ढंग से उपयोग नहीं किया जाता है - या तो बहुत सारे हैं और संदर्भ स्विचिंग का एक टन है, संसाधनों के एक ही सेट के लिए प्रतिस्पर्धा है, कार्य बहुत छोटे हैं। ओएस थ्रेड का सही तरीके से उपयोग करने के तरीके और प्रोग्राम के निष्पादन के संदर्भ में सर्वोत्तम तरीके से आवेदन करने के तरीके को समझने में अधिक समय लगता है।

ओएस इन दोनों कार्यों को मुफ्त में प्रदान करता है।

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

  • मान लें कि आप एक कैसीनो में कर रहे हैं:

    समय वितरण के इस सादृश्य पर विचार करें। ऐसे लोग हैं जो कार्ड चाहते हैं।

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

आप डीलरों से कार्ड वितरित करने के लिए कैसे कहेंगे?

ओएस शेड्यूलर के तहत, यह (थ्रेड) प्राथमिकता पर आधारित होगा। प्रत्येक व्यक्ति को एक समय में एक कार्ड दिया जाएगा (सीपीयू समय), और प्राथमिकता का निरंतर मूल्यांकन किया जाएगा।

लोग कार्य या धागे के काम का प्रतिनिधित्व करते हैं। कार्ड समय और संसाधनों का प्रतिनिधित्व करते हैं। डीलरों धागे और संसाधनों का प्रतिनिधित्व करते हैं।

यदि 2 डीलर और 3 लोग थे तो आप सबसे तेजी से कैसे निपटेंगे? और यदि 5 डीलर और 500 लोग थे? सौदे करने के लिए कार्ड से बाहर निकलने से आप कैसे कम कर सकते हैं? धागे के साथ, कार्ड जोड़ने और डीलरों को जोड़ने का कोई समाधान नहीं है जिसे आप 'मांग पर' दे सकते हैं। सीपीयू जोड़ना डीलरों को जोड़ने के बराबर है। थ्रेड जोड़ना एक समय में अधिक लोगों को कार्ड से निपटने वाले डीलरों के बराबर है (संदर्भ स्विचिंग बढ़ता है)। कार्ड को अधिक तेज़ी से निपटाने के लिए कई रणनीतियां हैं, खासकर जब आप निश्चित समय में कार्ड की लोगों की आवश्यकता को खत्म कर देते हैं। क्या एक टेबल पर जाने के लिए तेज़ नहीं होगा और जब तक कि लोगों के अनुपात में डीलर 1/50 नहीं था, तब तक उनका खेल पूरा होने तक किसी व्यक्ति या लोगों से निपटना नहीं होगा? प्राथमिकता के आधार पर प्रत्येक तालिका पर जाने और सभी डीलरों (ओएस दृष्टिकोण) के बीच विज़िट समन्वय करने के लिए इसकी तुलना करें। इसका मतलब यह नहीं है कि ओएस बेवकूफ है - इसका तात्पर्य है कि ओएस थ्रेड बनाना एक इंजीनियर है जो अधिक लोगों और अधिक तालिकाओं को जोड़ता है, संभावित रूप से डीलरों से अधिक उचित रूप से संभाल सकता है। सौभाग्य से, अन्य मल्टीथ्रेडिंग मॉडल और उच्च abstractions का उपयोग करके कई मामलों में बाधाओं को उठाया जा सकता है।

ओएस थ्रेड "हरे" धागे से अधिक महंगा क्यों होना चाहिए? प्रत्येक "कार्य" के लिए समर्पित ओएस थ्रेड होने के कारण अनुमानित प्रदर्शन में गिरावट का कारण क्या है?

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

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

6

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

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

तो, एक शेड्यूलिंग रन काफी जटिल आपरेशन हो सकता है।

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

चूंकि कुछ भी नहीं है, हरे धागे के साथ समस्याएं हैं। वे 'वास्तविक' ओएस धागे से दौड़ते हैं। इसका मतलब यह है कि यदि एक ओएस थ्रेड द्वारा चलाए गए समूह में एक 'हरा' धागा एक ओएस कॉल करता है जो ब्लॉक करता है, तो समूह में सभी हरे धागे अवरुद्ध होते हैं। इसका मतलब है कि नींद() जैसे साधारण कॉल को एक राज्य-मशीन द्वारा 'नकली' होना चाहिए जो अन्य हरे धागे को उत्पन्न करता है, (हाँ, ओएस को फिर से कार्यान्वित करने की तरह)। इसी प्रकार, किसी भी अंतर-थ्रेड सिग्नलिंग।

इसके अलावा, हरे रंग के धागे सीधे आईओ सिग्नलिंग का जवाब नहीं दे सकते हैं, इसलिए कुछ जगहों पर किसी भी थ्रेड को हराकर कुछ हद तक हराया जाता है।

1

A person in Google shows an interesting approach.

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