SwitchToThread() नींद का एक "स्मार्ट" संस्करण है (0)। यह अच्छी तरह से प्रलेखित नहीं है, लेकिन मेरी समझ में, यह निम्नलिखित तरीके से काम करता है:
- जब वहाँ
ready
राज्य में अन्य धागे हैं (यानी एक से अधिक तार्किक प्रोसेसर उपलब्ध हैं चलाने के लिए इच्छुक धागे हैं) और इन थ्रेड हैं जो समान या उच्च प्राथमिकता है जो स्विचटो थ्रेड() को कॉल करने वाले थ्रेड की तुलना में व्यवहार करता है जैसे स्लीप (0) - यानी संदर्भों की महंगी लागत पर इन धागे में से किसी एक को लॉजिकल प्रोसेसर को सीड करता है स्विच;
- जब वहाँ कम प्राथमिकता साथ
ready
राज्य में सूत्र, यह सिर्फ बाहर निकल जाता है, धागा कि SwitchToThread() का आह्वान किया है यानी एक संदर्भ स्विच के किसी भी खर्च या एक 3 अंगूठी करने के लिए 0 संक्रमण (यह नहीं छोड़ता बिना निष्पादन जारी है उपयोगकर्ता मोड) - यह है कि कैसे नींद (0) व्यवहार करता है जो हमेशा से सबसे कम प्राथमिकता धागे पर नियंत्रण करता है;
- जब
ready
स्थिति में कोई थ्रेड नहीं है, तो SwitchToThread() भी स्लीप (0) जैसे बाहर निकलता है - इसलिए यदि आप इसे लूप में करते हैं, तो आपको वर्तमान लॉजिकल प्रोसेसर का 100% भार मिल रहा है, यानी शक्ति जल रहा है।
नींद (1) नींद (0) के समान है लेकिन 1 मिलीसेकंद देरी के साथ ही है। यह 1 मिलीसेकंद देरी तार्किक प्रोसेसर को मुक्त करती है और किसी भी शक्ति को जला नहीं देती है। इसके विपरीत, स्विच टॉथ्रेड, कभी भी किसी भी देरी का अनुभव नहीं करता है।
तो स्लीप (1) के साथ स्विचटो थ्रेड की तुलना करना बेहतर है, नींद (1) के साथ नहीं, क्योंकि नींद (1) स्लीप (0) + 1 मिलीसेकंड की देरी के समान है।
मैंने इस मुद्दे पर "इंटेल 64 और आईए -32 आर्किटेक्चर ऑप्टिमाइज़ेशन रेफरेंस मैनुअल" और "इंटेल 64 और आईए -32 आर्किटेक्चर सॉफ्टवेयर डेवलपर मैनुअल" से कुछ विचार उधार लिया है, जो कुछ pause
सीपीयू निर्देशों को भी कॉल करने का पक्ष लेते हैं (यह भी Intrinsics के रूप में उपलब्ध) SwitchToThread() या नींद (0) पर यदि आपका इंतजार बहुत छोटा है। कृपया ध्यान दें कि SwitchToThread() या नींद (0) लगभग तत्काल हैं, जबकि नींद (1) कम से कम एक मिलीसेकंद तक रहता है।
निम्नलिखित को भी ध्यान में रखा जाना चाहिए:
- प्रत्येक कॉल नींद के लिए() या SwitchToThread() एक संदर्भ स्विच है, जो 10000+ चक्र हो सकता है की महंगी लागत अनुभव करता है।
- यह 0 रिंग 0 संक्रमणों के लिए रिंग 3 की लागत भी पीड़ित है, जो 1000+ चक्र हो सकता है।
- स्विचटो थ्रेड() या नींद (0) का कोई उपयोग नहीं हो सकता है यदि
ready
राज्य में कोई धागा नहीं है, लेकिन नींद (1) कम से कम एक मिलीसेकंड की प्रतीक्षा करता है चाहे इस पर 'तैयार' राज्य में अन्य धागे हैं या नहीं नहीं।
यदि आपका प्रतीक्षा लूप बहुत छोटा हो जाता है, तो कृपया कुछ pause
CPU निर्देशों को पहले निष्पादित करने पर विचार करें। अधिक संसाधनों के अधिग्रहण के लिए इंतज़ार कर रहे कार्यों को सुविधाजनक बनाने के
- प्रदर्शन: नीचे SwitchToThread (से पहले कुछ
pause
सीपीयू निर्देश के साथ "स्पिन प्रतीक्षा") या एक नींद() कॉल, बहु सूत्रण सॉफ्टवेयर लाभ को धीमा करके व्यस्त प्रतीक्षा से आसानी से।
- कताई के दौरान पाइपलाइन के कम हिस्सों का उपयोग करके दोनों द्वारा पावर-बचत।
- स्विचटो थ्रेड() या नींद (0) या नींद (1) कॉल के ऊपरी हिस्से के कारण अनावश्यक रूप से निष्पादित निर्देशों के बहुमत का उन्मूलन।
हालांकि, अगर आप नींद कॉल करने के लिए जा रहे हैं (1) जो कम से कम एक millisecond जो CPU चक्र के मामले में बहुत लंबा है, की तुलना में आप उम्मीद कर रहे हैं कि आपके इंतजार चक्र बहुत लंबा हो जाएगा, इसलिए pause
चलाता है इस मामले में निर्देश व्यर्थ होंगे।
जब प्रतीक्षा लूप लंबे समय तक रहने की उम्मीद है, तो ओएस सिंक्रनाइज़ेशन एपीआई फ़ंक्शंस में से एक को कॉल करके ऑपरेटिंग सिस्टम को उपज करना बेहतर है, जैसे विंडोज ओएस पर WaitForSingleObject, लेकिन SwitchToThread() या नींद नहीं (0) या नींद (1), क्योंकि वे लंबे इंतजार पर बहुत अपमानजनक हैं। इसके अलावा, नींद (1) बहुत धीमी है और ओएस सिंक्रनाइज़ेशन फ़ंक्शन जैसे WaitForSingleObject या EnterCriticalSection बहुत अधिक प्रतिक्रिया देंगे और वे अधिक संसाधन-अनुकूल हैं।
मेरा निष्कर्ष: नींद (0) या नींद (1) या SwitchToThread() का उपयोग न करना बेहतर है। हर कीमत पर "स्पिन-प्रतीक्षा" लूप से बचें। WaitForMultipleObjects(), SetEvent(), और इसी तरह उच्च-स्तरीय सिंक्रनाइज़ेशन फ़ंक्शंस का उपयोग करें - वे प्रदर्शन, दक्षता और पावर सेविंग की शर्तों से श्रेष्ठ हैं।यद्यपि वे महंगे संदर्भ स्विच और रिंग 3 से रिंग 0 संक्रमणों तक भी पीड़ित हैं, लेकिन ये खर्च कम हैं (नींद() या स्विचटॉथ्रेड() के साथ "स्पिन-वेट" लूप में जो खर्च किया गया है उससे तुलना में उचित हैं।
एचटी टेक्नोलॉजी का समर्थन करने वाले प्रोसेसर पर, स्पिन-प्रतीक्षा लूप प्रोसेसर के निष्पादन बैंडविड्थ का एक महत्वपूर्ण हिस्सा उपभोग कर सकते हैं। स्पिन-वेट लूप निष्पादित करने वाला एक लॉजिकल प्रोसेसर अन्य लॉजिकल प्रोसेसर के प्रदर्शन को गंभीर रूप से प्रभावित कर सकता है। यही कारण है कि कभी-कभी एचटी को अक्षम करने से प्रदर्शन में सुधार हो सकता है।
राज्य परिवर्तनों के लिए किसी डिवाइस या फ़ाइल या अन्य डेटा स्रोत के लिए लगातार मतदान करना कंप्यूटर को स्मृति, सिस्टम बस पर तनाव डालने और अनावश्यक पृष्ठ दोष प्रदान करने के लिए कारण बन सकता है (कार्य प्रबंधक का उपयोग करें विंडोज़ यह देखने के लिए कि कौन से अनुप्रयोग निष्क्रिय होने के दौरान अधिकांश पेज दोष उत्पन्न करते हैं - ये "अक्षम" का उपयोग कर रहे हैं क्योंकि ये सबसे अक्षम अनुप्रयोग हैं)। जब भी संभव हो मतदान मतदान को कम करें और आवेदन लिखने के एक घटना संचालित तरीके का उपयोग करें। यह सबसे अच्छा अभ्यास है जिसे मैं अत्यधिक अनुशंसा करता हूं। अग्रिम में स्थापित कई कार्यक्रमों की प्रतीक्षा करते हुए, आपको आवेदन हर समय सचमुच सोना चाहिए। घटना-संचालित एप्लिकेशन का एक अच्छा उदाहरण लिनक्स के तहत निजिनक्स है। पावर स्रोत परिवर्तनों के लिए मतदान के साथ एक उदाहरण लें। यदि एक ऑपरेटिंग सिस्टम विभिन्न डिवाइस राज्य परिवर्तनों के लिए अधिसूचना सेवाएं (यहां तक कि एक डब्लूएम_ संदेश) प्रदान करता है, जैसे कि एसी से बैटरी तक बिजली स्रोत को स्थानांतरित करना, डिवाइस स्थिति परिवर्तनों के लिए मतदान के बजाय इन अधिसूचना सेवाओं का उपयोग करें। इस तरह के दृष्टिकोण से कोड के लिए पावर स्रोत की स्थिति को प्रदूषित करने के लिए ओवरहेड कम हो जाता है, क्योंकि जब स्थिति में परिवर्तन होता है तो कोड अधिसूचनाएं असीमित रूप से प्राप्त कर सकता है।
कुछ लोगों ने जो लिखा है उसके विपरीत, नींद (0) CPU खपत को शून्य के करीब नहीं कम करता है। यह 'तैयार' स्थिति में मौजूद अन्य धागे को निष्पादन जारी करता है, लेकिन यदि ऐसे कोई धागे नहीं हैं, तो यह हजारों CPU चक्रों को बर्बाद कर देता है और वर्तमान धागे के 100% CPU चक्रों का उपभोग करता है, जैसा कि demonstrated by stackoverflow members भी है - और मेरे पास भी है बस इसे दोबारा जांचें - नींद (0) पाश विंडोज 10 64-बिट पर मौजूदा थ्रेड के 100% सीपीयू का उपभोग करती है।
आपके विश्लेषण को देखते हुए, 'if (! SwitchToThread()) नींद (0) नहीं कर रहा है, तो सबसे अच्छा समाधान हो सकता है? – wilx