Microsoft का अतुल्यकालिक दृष्टिकोण मल्टीथ्रेडेड प्रोग्रामिंग के लिए सबसे आम उद्देश्यों में से एक अच्छा विकल्प है: IO कार्यों के संबंध में जवाबदेही में सुधार करना।
हालांकि, यह महसूस करना महत्वपूर्ण है कि अतुल्यकालिक दृष्टिकोण सीपीयू के गहन कार्यों के संबंध में प्रदर्शन में सुधार, या जवाबदेही में सुधार करने में सक्षम नहीं है।
जवाबदेही के लिए बहुआयामी
जवाबदेही के लिए बहुआयामी एक कार्यक्रम है जो भारी IO कार्यों या भारी संगणना कार्यों के दौरान कार्यक्रम को उत्तरदायी बनाए रखने के लिए है। आप एक पृष्ठभूमि थ्रेड पर फ़ाइलों को सहेजते हैं, ताकि उपयोगकर्ता अपना काम जारी रख सके, बिना अपना काम खत्म करने के लिए हार्ड ड्राइव की प्रतीक्षा करें। IO थ्रेड अक्सर लिखने के कुछ हिस्से के खत्म होने का इंतजार करता है, इसलिए संदर्भ स्विच अक्सर होते हैं।
इसी तरह, एक जटिल गणना करते समय, आप नियमित संदर्भ स्विचिंग की अनुमति देना चाहते हैं ताकि यूआई उत्तरदायी बने रह सकें, और उपयोगकर्ता को नहीं लगता कि कार्यक्रम क्रैश हो गया है।
यहाँ लक्ष्य सामान्य रूप से, विभिन्न सीपीयू पर चलने के लिए कई थ्रेड्स प्राप्त करने के लिए नहीं है। इसके बजाय, हम केवल लंबे समय से चल रहे पृष्ठभूमि कार्य और UI के बीच होने वाले संदर्भ स्विच प्राप्त करने में रुचि रखते हैं, ताकि पृष्ठभूमि कार्य चलने के दौरान UI उपयोगकर्ता को अपडेट और प्रतिक्रिया करने में सक्षम हो। सामान्य तौर पर, यूआई बहुत सीपीयू पावर नहीं लेगा, और थ्रेडिंग फ्रेमवर्क या ओएस आमतौर पर उन्हें एक ही सीपीयू पर चलाने का फैसला करेगा।
हम वास्तव में संदर्भ स्विचिंग की अतिरिक्त लागत के कारण समग्र प्रदर्शन खो देते हैं, लेकिन हमें परवाह नहीं है क्योंकि सीपीयू का प्रदर्शन हमारा लक्ष्य नहीं था। हम जानते हैं कि आमतौर पर हमारे पास जरूरत से ज्यादा सीपीयू की शक्ति होती है, और इसलिए मल्टीथ्रेडिंग के संबंध में हमारा लक्ष्य उपयोगकर्ता के समय को बर्बाद किए बिना उपयोगकर्ता के लिए एक कार्य करना है।
"एसिंक्रोनस" वैकल्पिक
"एसिंक्रोनस अप्रोच" एक धागे के भीतर संदर्भ स्विच को सक्षम करके इस तस्वीर को बदल देता है। यह गारंटी देता है कि हमारे सभी कार्य एक ही सीपीयू पर चलेंगे, और थ्रेड्स के बीच कम थ्रेड निर्माण / क्लीनअप और कम वास्तविक संदर्भ स्विच के संदर्भ में कुछ मामूली प्रदर्शन सुधार प्रदान कर सकते हैं।
नेटवर्क संसाधन (जैसे कोई छवि डाउनलोड करना) की प्राप्ति की प्रतीक्षा करने के लिए एक नया थ्रेड बनाने के बजाय, एक async
विधि का उपयोग किया जाता है, जो await
छवि उपलब्ध हो रही है, और इस बीच, कॉलिंग विधि के लिए पैदावार करता है।
यहाँ मुख्य लाभ यह है कि आपको गतिरोध से बचने जैसे मुद्दों के बारे में चिंता करने की ज़रूरत नहीं है, क्योंकि आप ताले और तुल्यकालन का उपयोग बिल्कुल नहीं कर रहे हैं, और प्रोग्रामर के लिए पृष्ठभूमि थ्रेड स्थापित करने और वापस आने के लिए थोड़ा कम काम है। UI को सुरक्षित रूप से अपडेट करने के लिए परिणाम आने पर UI थ्रेड पर।
मैंने तकनीकी विवरणों में बहुत गहराई से नहीं देखा है, लेकिन मेरी धारणा यह है कि कभी-कभार सीपीयू गतिविधि के साथ डाउनलोड का प्रबंधन करना एक अलग धागे के लिए नहीं बल्कि यूआई इवेंट कतार में एक कार्य की तरह कुछ और भी अधिक हो जाता है, और जब डाउनलोड पूर्ण हो जाता है, अतुल्यकालिक विधि को उस घटना कतार से फिर से शुरू किया जाता है। दूसरे शब्दों में, await
कुछ का अर्थ है "जांचना कि क्या परिणाम की मुझे आवश्यकता है उपलब्ध है, यदि नहीं, तो मुझे इस धागे के कार्य कतार में वापस रख दें"।
ध्यान दें कि यह दृष्टिकोण सीपीयू-गहन कार्य की समस्या को हल नहीं करेगा: प्रतीक्षा करने के लिए कोई डेटा नहीं है, इसलिए हम एक वास्तविक पृष्ठभूमि कार्यकर्ता थ्रेड बनाए बिना संदर्भ स्विच प्राप्त नहीं कर सकते हैं। बेशक, पृष्ठभूमि के थ्रेड को शुरू करने और परिणाम को वापस करने के लिए एक अतुल्यकालिक विधि का उपयोग करना अभी भी सुविधाजनक हो सकता है, एक कार्यक्रम में जो अतुल्यकालिक दृष्टिकोण का उपयोग करता है।
प्रदर्शन के लिए बहुआयामी
चूंकि आप "प्रदर्शन" के बारे में बात करते हैं, इसलिए मैं यह भी चर्चा करना चाहूंगा कि प्रदर्शन लाभ के लिए मल्टीथ्रेडिंग का उपयोग कैसे किया जा सकता है, कुछ ऐसा है जो एकल-थ्रेडेड अतुल्यकालिक दृष्टिकोण के साथ पूरी तरह से असंभव है।
जब आप वास्तव में ऐसी स्थिति में होते हैं जहां आपके पास एक सीपीयू पर पर्याप्त सीपीयू शक्ति नहीं होती है, और प्रदर्शन के लिए मल्टीथ्रेडिंग का उपयोग करना चाहते हैं, तो वास्तव में ऐसा करना मुश्किल होता है। दूसरी ओर, यदि एक सीपीयू पर्याप्त प्रसंस्करण शक्ति नहीं है, तो यह अक्सर एकमात्र समाधान होता है जो आपके कार्यक्रम को वह करने में सक्षम बनाता है जो आप एक उचित समय सीमा में पूरा करना चाहते हैं, जो कि काम को सार्थक बनाता है।
तुच्छ समानता
बेशक, कभी-कभी मल्टीथ्रेडिंग से वास्तविक स्पीडअप प्राप्त करना आसान हो सकता है।
यदि आपके पास बड़ी संख्या में स्वतंत्र संगणना-गहन कार्य होते हैं (अर्थात, ऐसे कार्य जिनके इनपुट और आउटपुट डेटा गणना के संबंध में बहुत छोटे हैं, जो परिणाम निर्धारित करने के लिए किए जाने चाहिए), तो आप अक्सर महत्वपूर्ण स्पीडअप प्राप्त कर सकते हैं थ्रेड्स का एक पूल बनाना (उपलब्ध सीपीयू की संख्या के आधार पर उचित आकार), और एक मास्टर थ्रेड काम को वितरित करता है और परिणाम एकत्र करता है।
प्रदर्शन के लिए प्रैक्टिकल मल्टीथ्रेडिंग
मैं खुद को एक विशेषज्ञ के रूप में बहुत आगे नहीं रखना चाहता, लेकिन मेरी धारणा यह है कि सामान्य तौर पर, इन दिनों होने वाले प्रदर्शन के लिए सबसे व्यावहारिक मल्टीथ्रेडिंग, एक आवेदन में स्थानों की तलाश में है जो तुच्छ समानताएं हैं, और कई थ्रेड्स का उपयोग कर रहे हैं लाभ पाने के लिए।
किसी भी अनुकूलन के साथ, आमतौर पर आपके कार्यक्रम के प्रदर्शन की रूपरेखा तैयार करने के बाद इसे अनुकूलित करना बेहतर होता है, और हॉट स्पॉट की पहचान की जाती है: मनमाने ढंग से यह तय करके किसी कार्यक्रम को धीमा करना आसान है कि यह भाग एक धागे में और दूसरे भाग में, बिना पहले यह निर्धारित करना कि दोनों भाग सीपीयू समय का एक महत्वपूर्ण हिस्सा ले रहे हैं या नहीं।
एक अतिरिक्त थ्रेड का अर्थ है अधिक सेटअप / टैडडाउन लागत, और या तो अधिक संदर्भ स्विच या अधिक अंतर-सीपीयू संचार लागत। यदि यह उन लागतों के लिए एक अलग सीपीयू पर बनाने के लिए पर्याप्त काम नहीं कर रहा है, और जवाबदेही कारणों के लिए एक अलग धागा होने की आवश्यकता नहीं है, तो यह बिना किसी लाभ के चीजों को धीमा कर देगा।
ऐसे कार्यों को देखें जिनकी कुछ अन्योन्याश्रितियाँ हैं, और जो आपके प्रोग्राम के रनटाइम का एक महत्वपूर्ण हिस्सा ले रहे हैं।
यदि उनकी कोई अन्य निर्भरता नहीं है, तो यह तुच्छ समानता का मामला है, आप आसानी से प्रत्येक को एक धागे के साथ सेट कर सकते हैं और लाभों का आनंद ले सकते हैं।
यदि आप सीमित अंतरनिर्भरता के साथ कार्य पा सकते हैं, ताकि सूचनाओं के आदान-प्रदान के लिए लॉकिंग और सिंक्रोनाइज़ेशन उन्हें धीमा न करें, तो मल्टीथ्रेडिंग कुछ गति प्रदान कर सकता है, बशर्ते आप सिंक्रनाइज़ किए जाने पर दोषपूर्ण तर्क के कारण गतिरोध के खतरों से बचने के लिए सावधान रहें। आवश्यक होने पर सिंक्रनाइज़ नहीं करने के कारण गलत परिणाम।
वैकल्पिक रूप से, मल्टीथ्रेडिंग के लिए कुछ अधिक सामान्य अनुप्रयोग (एक अर्थ में) पूर्व निर्धारित एल्गोरिथ्म की गति की तलाश में नहीं हैं, लेकिन इसके बजाय एल्गोरिथ्म के एक बड़े बजट के लिए वे लिखने की योजना बना रहे हैं: यदि आप गेम इंजन लिख रहे हैं , और आपके एआई को आपके फ्रेम दर के भीतर एक निर्णय करना है, तो आप अक्सर अपने एआई को एक बड़ा सीपीयू चक्र बजट दे सकते हैं यदि आप इसे अपना स्वयं का सीपीयू दे सकते हैं।
हालांकि, थ्रेड्स को प्रोफाइल करना सुनिश्चित करें और सुनिश्चित करें कि वे कुछ बिंदु पर लागत के लिए पर्याप्त काम कर रहे हैं।
समानांतर एल्गोरिदम
वहाँ भी कई समस्याएं हैं जो कई प्रोसेसर का उपयोग करके स्पेड किया जा सकता है, लेकिन यह केवल सीपीयू के बीच विभाजन करने के लिए बहुत अखंड हैं।
समानांतर एल्गोरिदम को अपने बिग-ओ रनटाइम के लिए सबसे अच्छा उपलब्ध गैर-समानांतर एल्गोरिदम के संबंध में सावधानीपूर्वक विश्लेषण करना होगा, क्योंकि यह कई सीपीयू का उपयोग करने से किसी भी लाभ को खत्म करने के लिए अंतर-सीपीयू संचार लागत के लिए बहुत आसान है। सामान्य तौर पर, वे प्रत्येक सीपीयू पर गणना का उपयोग करने से कम अंतर-सीपीयू संचार (बड़े-ओ शब्दों में) का उपयोग करना चाहिए।
फिलहाल, यह अभी भी काफी हद तक अकादमिक अनुसंधान के लिए एक जगह है, क्योंकि आंशिक विश्लेषण की आवश्यकता है, भाग में क्योंकि तुच्छ समानता काफी सामान्य है, क्योंकि हम अभी तक हमारे कंप्यूटरों पर इतने सीपीयू कोर नहीं हैं जो समस्याएं हैं जो एक सीपीयू पर एक उचित समय सीमा में हल नहीं किया जा सकता है हमारे सभी सीपीयू का उपयोग करके उचित समय सीमा में हल किया जा सकता है।