प्रदर्शन में सुधार के लिए बहु-सूत्रण को अक्सर क्यों पसंद किया जाता है?


23

मेरे पास एक सवाल है, यह इस बारे में है कि प्रोग्रामर सामान्य रूप से संगामिति और बहु-थ्रेडेड कार्यक्रमों से प्यार क्यों करते हैं।

मैं यहां 2 मुख्य दृष्टिकोणों पर विचार कर रहा हूं:

  • मूल रूप से संकेतों के आधार पर एक async दृष्टिकोण, या उदाहरण के लिए नए C # 5.0 जैसे कई कागजात और भाषाओं द्वारा बुलाया गया एक async दृष्टिकोण, और एक "साथी धागा" जो आपकी पाइपलाइन की नीति का प्रबंधन करता है
  • समवर्ती दृष्टिकोण या बहु सूत्रण दृष्टिकोण

मैं सिर्फ यह कहूंगा कि मैं यहां हार्डवेयर और सबसे खराब स्थिति के बारे में सोच रहा हूं, और मैंने खुद इस 2 प्रतिमानों का परीक्षण किया है, इस बिंदु पर async प्रतिमान एक विजेता है जो मुझे नहीं मिलता है कि लोगों को 90% समय क्यों मिलता है मल्टी-थ्रेडिंग के बारे में बात करें जब वे चीजों को गति देना चाहते हैं या अपने संसाधनों का अच्छा उपयोग करना चाहते हैं।

मैंने एक पुरानी मशीन पर मल्टी-थ्रेडेड प्रोग्राम और एसिंक्स प्रोग्राम को इंटेल क्वाड-कोर के साथ परीक्षण किया है जो सीपीयू के अंदर मेमोरी कंट्रोलर की पेशकश नहीं करता है, मेमोरी पूरी तरह से मदरबोर्ड द्वारा प्रबंधित की जाती है, इस मामले में प्रदर्शन एक मल्टी के साथ भयानक हैं बहु-थ्रेडेड एप्लिकेशन, यहां तक ​​कि थ्रेड्स की अपेक्षाकृत कम संख्या जैसे 3-4-5 एक समस्या हो सकती है, एप्लिकेशन अप्रतिसादी है और बस धीमा और अप्रिय है।

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

मैंने यह भी पता लगाया है कि थ्रेडिंग की दुनिया में एक संदर्भ परिवर्तन यह वास्तविक दुनिया के परिदृश्य में सस्ता नहीं है, यह वास्तव में काफी महंगा है, जब आपके पास 2 से अधिक धागे हैं जिन्हें गणना करने के लिए एक दूसरे के बीच चक्र और स्वैप करने की आवश्यकता होती है।

आधुनिक सीपीयू की स्थिति पर यह वास्तव में अलग नहीं है, मेमोरी कंट्रोलर यह एकीकृत है, लेकिन मेरा कहना है कि एक x86 सीपीयू मूल रूप से एक सीरियल मशीन है और मेमोरी कंट्रोलर उसी तरह काम करता है जैसे पुरानी मशीन के साथ मदरबोर्ड पर बाहरी मेमोरी कंट्रोलर। । संदर्भ स्विच अभी भी मेरे आवेदन में एक प्रासंगिक लागत है और यह तथ्य कि स्मृति नियंत्रक यह एकीकृत है या कि नए सीपीयू में 2 से अधिक कोर हैं, यह मेरे लिए सौदेबाजी नहीं है।

जो मैंने समवर्ती दृष्टिकोण का अनुभव किया है, वह सिद्धांत में अच्छा है, लेकिन व्यवहार में अच्छा नहीं है, हार्डवेयर द्वारा लगाए गए मेमोरी मॉडल के साथ, इस प्रतिमान का अच्छा उपयोग करना कठिन है, यह उपयोग से लेकर कई मुद्दों का परिचय देता है मेरे डेटा संरचनाओं में कई थ्रेड्स शामिल होने के लिए।

साथ ही दोनों प्रतिमान कार्य या कार्य को निश्चित समय में एक निश्चित समय में पूरा करने के बाद किसी भी सुरक्षा व्यवस्था की पेशकश नहीं करते हैं, जिससे वे वास्तव में एक कार्यात्मक दृष्टिकोण से समान हो जाते हैं।

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


2
तुलना करने का एक तरीका जावास्क्रिप्ट दुनिया को देखना होगा, क्या कोई थ्रेडिंग नहीं थी और कमियों का उपयोग करके सब कुछ आक्रामक रूप से अतुल्यकालिक है। यह काम करता है, लेकिन इसके अपने मुद्दे हैं।
रोबोट डिस

2
@StevenBurnap आप वेब कर्मचारियों को क्या कहते हैं?
user16764

2
"यहां तक ​​कि 3-4-5 जैसे थ्रेड्स की अपेक्षाकृत कम संख्या एक समस्या हो सकती है, आवेदन अप्रतिसादी है और बस धीमा और अप्रिय है।" => यह खराब डिज़ाइन / थ्रेड के अनुचित उपयोग के कारण हो सकता है। आप आमतौर पर उस तरह की स्थिति पाते हैं जब आपके थ्रेड्स डेटा का आदान-प्रदान करते रहते हैं, जिस स्थिति में मल्टी थ्रेडिंग सही उत्तर नहीं हो सकता है या आपको डेटा को फिर से विभाजित करने की आवश्यकता हो सकती है।
assylias

1
@assylias UI थ्रेड में एक महत्वपूर्ण धीमा देखने के लिए थ्रेड्स में लॉकिंग की एक अत्यधिक मात्रा इंगित करता है। आपके पास या तो एक खराब कार्यान्वयन है या आप एक गोल छेद में एक वर्ग खूंटी को पाउंड करने की कोशिश कर रहे हैं।
इवान प्लाइस

5
आप कहते हैं "प्रोग्रामर सामान्य रूप से संगामिति और बहु-थ्रेडेड कार्यक्रमों से प्यार करते हैं" मुझे संदेह है कि। मैं कहूंगा कि "प्रोग्रामर्स इससे नफरत करते हैं" ... लेकिन अक्सर ऐसा करने के लिए केवल उपयोगी चीज होती है ...
जोहान्स

जवाबों:


34

आपके पास कई कोर / प्रॉसेसर्स हैं, उनका उपयोग करें

Async है भारी सीपीयू बाध्य प्रसंस्करण के बारे में भारी आईओ बाध्य प्रसंस्करण लेकिन क्या कर के लिए सबसे अच्छा?

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

एक बहु-थ्रेडेड एप्लिकेशन में, सीपीयू-गहन कार्यों (एक प्रिंट नौकरी से पूर्व) को एक पृष्ठभूमि कार्यकर्ता थ्रेड में भेजा जा सकता है जिससे यूआई थ्रेड को मुक्त किया जा सकता है।

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

व्यवहार में, async और मल्टी-थ्रेडेड / प्रोसेस कोड प्रत्येक के पास अपने लाभ और कमियां हैं।

आप प्रमुख क्लाउड प्लेटफार्मों में रुझान देख सकते हैं, क्योंकि वे सीपीयू बाउंड प्रोसेसिंग के लिए विशेष और आईओ बाउंड प्रोसेसिंग के लिए विशेष इंस्टेंस प्रस्तुत करेंगे।

उदाहरण:

  • स्टोरेज (अमेज़ॅन S3, Google क्लाउड ड्राइव) सीपीयू बाध्य है
  • वेब सर्वर IO बाउंड हैं (Amazon EC2, Google App Engine)
  • डेटाबेस दोनों हैं, CPU लिखने / अनुक्रमण के लिए बाध्य है और IO रीड के लिए बाध्य है

इसे परिप्रेक्ष्य में रखने के लिए ...

एक वेबसर्वर एक मंच का एक आदर्श उदाहरण है जो दृढ़ता से IO बाध्य है। एक बहु-थ्रेडेड वेबसर्वर जो प्रति कनेक्शन एक थ्रेड असाइन करता है, अच्छी तरह से स्केल नहीं करता है क्योंकि हर थ्रेड अधिक स्विचिंग के कारण संदर्भ स्विचिंग और साझा संसाधनों पर थ्रेड लॉकिंग की अधिक मात्रा के कारण होता है। जबकि एक async वेबसर्वर एकल पता स्थान का उपयोग करेगा।

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

सबसे अच्छा अनुप्रयोग अक्सर दोनों के संयोजन का उपयोग करता है। उदाहरण के लिए, एक वेबप, आने वाले अनुरोधों की धार को प्रबंधित करने के लिए लोड बैलेंसर के रूप में nginx (यानी async सिंगल-थ्रेडेड) का उपयोग कर सकता है, http अनुरोधों को संभालने के लिए एक समान async वेबसर्वर (पूर्व Node.js) और बहु-थ्रेडेड सर्वर का एक सेट। अपलोड / स्ट्रीमिंग / एन्कोडिंग सामग्री, आदि को संभालना ...

मल्टी-थ्रेडेड, मल्टी-प्रोसेस और एसिंक्स मॉडल के बीच कई वर्षों में बहुत सारे धार्मिक युद्ध हुए हैं। सबसे अधिक चीजों के साथ सबसे अच्छा जवाब वास्तव में होना चाहिए, "यह निर्भर करता है।"

यह सोचने की एक ही पंक्ति का अनुसरण करता है जो समानांतर में GPU और CPU आर्किटेक्चर का उपयोग करने को सही ठहराता है। कॉन्सर्ट में चल रहे दो विशेष प्रणालियों में एकल अखंड दृष्टिकोण की तुलना में बहुत अधिक सुधार हो सकता है।

न ही बेहतर हैं क्योंकि दोनों का उपयोग होता है। नौकरी के लिए बेहतरीन टूल का इस्तेमाल करें।

अद्यतन करें:

मैंने अपाचे के संदर्भ को हटा दिया और एक मामूली सुधार किया। अपाचे एक मल्टीप्रोसेस मॉडल का उपयोग करता है जो कर्नेल स्तर पर संदर्भ स्विचिंग की मात्रा में वृद्धि करने वाले हर अनुरोध के लिए एक प्रक्रिया की तलाश करता है। इसके अलावा, चूंकि मेमोरी को प्रक्रियाओं में साझा नहीं किया जा सकता है, प्रत्येक अनुरोध एक अतिरिक्त मेमोरी लागत लगाता है।

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

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

Update2:

नेटवर्क (यानी सॉकेट) संचार की तुलना में आईपीसी के बारे में कंबल बयान के विपरीत। हमेशा ऐसा नहीं होता । ध्यान रखें कि ये सामान्यीकरण हैं और कार्यान्वयन-विशिष्ट विवरण परिणाम पर भारी प्रभाव डाल सकते हैं।


एक प्रोग्रामर को मल्टी-प्रोसेस क्यों जाना चाहिए? मेरा मतलब है कि मैं मानता हूं कि 1 से अधिक प्रक्रिया के साथ आपको किसी प्रकार के अंतर-प्रक्रिया संचार की भी आवश्यकता होती है जो एक महत्वपूर्ण ओवरहेड जोड़ सकता है, क्या यह कुछ करने के पुराने विंडोज-प्रोग्रामर तरीके की तरह है? मुझे बहु-प्रक्रिया कब करनी चाहिए? वैसे आपके जवाब के लिए धन्यवाद, वास्तव में क्या async और बहु ​​लड़ी की अच्छी तस्वीर के लिए अच्छे हैं।
user1849534

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

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

1
@ akka.io आप पूरी तरह से सही हैं। अपरिवर्तनशीलता लॉकिंग के ओवरहेड को कम करने / समाप्त करने का एक तरीका है, लेकिन आप अभी भी संदर्भ स्विचिंग के समय की लागत को पूरा करते हैं। यदि आप विवरण को शामिल करने के लिए उत्तर का विस्तार करना चाहते हैं कि अपरिवर्तनशीलता थ्रेड सिंक्रोनाइज़ेशन समस्याओं को कैसे हल कर सकती है, तो बेझिझक। मुख्य बिंदु जो मैं वर्णन करना चाहता था, ऐसे मामले हैं जहां एसिंक्स संचार में बहु-थ्रेडेड / प्रक्रिया और इसके विपरीत पर एक अलग लाभ है।
इवान प्लाइस

(प्रतियोगिता) लेकिन, ईमानदारी से अगर मुझे सीपीयू-बाउंड प्रोसेसिंग क्षमता की बहुत आवश्यकता थी तो मैं अभिनेता मॉडल को छोड़ दूंगा और इसे कई नेटवर्किंग नोड्स में स्केल करने में सक्षम बनाऊंगा। इसके लिए मैंने जो सबसे अच्छा समाधान देखा है वह सॉकेट-स्तरीय संचार पर 0MQ के टास्क वेंटिलेटर मॉडल का उपयोग करना है। चित्र 5 @ zguide.zeromq.org/page:all देखें ।
इवान प्लाइस

13

Microsoft का अतुल्यकालिक दृष्टिकोण मल्टीथ्रेडेड प्रोग्रामिंग के लिए सबसे आम उद्देश्यों में से एक अच्छा विकल्प है: IO कार्यों के संबंध में जवाबदेही में सुधार करना।

हालांकि, यह महसूस करना महत्वपूर्ण है कि अतुल्यकालिक दृष्टिकोण सीपीयू के गहन कार्यों के संबंध में प्रदर्शन में सुधार, या जवाबदेही में सुधार करने में सक्षम नहीं है।

जवाबदेही के लिए बहुआयामी

जवाबदेही के लिए बहुआयामी एक कार्यक्रम है जो भारी IO कार्यों या भारी संगणना कार्यों के दौरान कार्यक्रम को उत्तरदायी बनाए रखने के लिए है। आप एक पृष्ठभूमि थ्रेड पर फ़ाइलों को सहेजते हैं, ताकि उपयोगकर्ता अपना काम जारी रख सके, बिना अपना काम खत्म करने के लिए हार्ड ड्राइव की प्रतीक्षा करें। IO थ्रेड अक्सर लिखने के कुछ हिस्से के खत्म होने का इंतजार करता है, इसलिए संदर्भ स्विच अक्सर होते हैं।

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

यहाँ लक्ष्य सामान्य रूप से, विभिन्न सीपीयू पर चलने के लिए कई थ्रेड्स प्राप्त करने के लिए नहीं है। इसके बजाय, हम केवल लंबे समय से चल रहे पृष्ठभूमि कार्य और UI के बीच होने वाले संदर्भ स्विच प्राप्त करने में रुचि रखते हैं, ताकि पृष्ठभूमि कार्य चलने के दौरान UI उपयोगकर्ता को अपडेट और प्रतिक्रिया करने में सक्षम हो। सामान्य तौर पर, यूआई बहुत सीपीयू पावर नहीं लेगा, और थ्रेडिंग फ्रेमवर्क या ओएस आमतौर पर उन्हें एक ही सीपीयू पर चलाने का फैसला करेगा।

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

"एसिंक्रोनस" वैकल्पिक

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

नेटवर्क संसाधन (जैसे कोई छवि डाउनलोड करना) की प्राप्ति की प्रतीक्षा करने के लिए एक नया थ्रेड बनाने के बजाय, एक asyncविधि का उपयोग किया जाता है, जो awaitछवि उपलब्ध हो रही है, और इस बीच, कॉलिंग विधि के लिए पैदावार करता है।

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

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

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

प्रदर्शन के लिए बहुआयामी

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

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

तुच्छ समानता

बेशक, कभी-कभी मल्टीथ्रेडिंग से वास्तविक स्पीडअप प्राप्त करना आसान हो सकता है।

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

प्रदर्शन के लिए प्रैक्टिकल मल्टीथ्रेडिंग

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

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

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

ऐसे कार्यों को देखें जिनकी कुछ अन्योन्याश्रितियाँ हैं, और जो आपके प्रोग्राम के रनटाइम का एक महत्वपूर्ण हिस्सा ले रहे हैं।

यदि उनकी कोई अन्य निर्भरता नहीं है, तो यह तुच्छ समानता का मामला है, आप आसानी से प्रत्येक को एक धागे के साथ सेट कर सकते हैं और लाभों का आनंद ले सकते हैं।

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

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

हालांकि, थ्रेड्स को प्रोफाइल करना सुनिश्चित करें और सुनिश्चित करें कि वे कुछ बिंदु पर लागत के लिए पर्याप्त काम कर रहे हैं।

समानांतर एल्गोरिदम

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

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

फिलहाल, यह अभी भी काफी हद तक अकादमिक अनुसंधान के लिए एक जगह है, क्योंकि आंशिक विश्लेषण की आवश्यकता है, भाग में क्योंकि तुच्छ समानता काफी सामान्य है, क्योंकि हम अभी तक हमारे कंप्यूटरों पर इतने सीपीयू कोर नहीं हैं जो समस्याएं हैं जो एक सीपीयू पर एक उचित समय सीमा में हल नहीं किया जा सकता है हमारे सभी सीपीयू का उपयोग करके उचित समय सीमा में हल किया जा सकता है।


एक स्पष्ट रूप से अच्छी तरह से सोचा जवाब के लिए +1। मैं हालांकि फेस वैल्यू पर Microsoft के सुझाव लेने के लिए सावधानी बरतूँगा। ध्यान रखें कि .NET एक सिंक्रोनस-प्रथम प्लेटफ़ॉर्म है, इसलिए पारिस्थितिकी तंत्र बेहतर सुविधा / प्रलेखन प्रदान करने के लिए पक्षपाती है जो सिंक्रोनाइज़ेशन समाधान का समर्थन करता है। विपरीत Node.js. की तरह एक async- पहले प्लेटफार्मों के लिए सच होगा
इवान प्लाइस

3

अनुप्रयोग अप्रतिसादी है और बस धीमा और अप्रिय है।

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

जहाँ तक mult बस ’में एक एसिंक्श दृष्टिकोण है, यह बहुस्तरीय है और यद्यपि अधिकांश वातावरण में एक विशेष उपयोग के मामले के लिए इसका उपयोग किया जाता है । दूसरों में, कि async coroutines के माध्यम से किया जाता है ... हमेशा समवर्ती नहीं होते हैं।

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


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