2008-08-05 24 views
37

में सीपीयू थ्रॉटलिंग मैं सोच रहा था कि क्या किसी विशेष थ्रेड के लिए गहन गणना करने के लिए अधिकतम CPU लोड सेट करने का एक शानदार तरीका है।

अभी मैं धागे में सबसे अधिक समय लेने वाला पाश (यह केवल संपीड़न करता है) स्थित है और GetTickCount() और Sleep() हार्डकोडेड मानों के साथ उपयोग करता है। यह सुनिश्चित करता है कि लूप एक निश्चित अवधि के लिए जारी रहता है और एक निश्चित न्यूनतम समय के लिए सो जाता है। यह नौकरी कम या ज्यादा करता है i.e. गारंटी देता है कि थ्रेड 50% से अधिक CPU का उपयोग नहीं करेगा।
हालांकि व्यवहार सीपीयू कोर (भारी नुकसान) और बस बदसूरत (छोटे नुकसान :)) की संख्या पर निर्भर है।
कोई विचार?सी ++

+1

आप किस दृश्य व्यवहार को प्राप्त करना चाहते हैं? यही है, यह वॉचडॉग आपके धागे से क्या चाहता है? क्या उन्हें सीपीयू का 80% कहने से अधिक का उपयोग नहीं करना चाहिए? निष्क्रिय रूप से निष्क्रिय आधार को निष्क्रिय करने के लिए निष्क्रिय आधार प्रक्रिया को सेट कर सकते हैं? – wordmonger

उत्तर

17

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

प्रत्येक पुनरावृत्ति को थ्रेड करने के लिए डिफ़ॉल्ट समय चुनें। फिर, प्रत्येक यात्रा पर (या हर वें यात्रा पर, थ्रॉटलिंग काम नहीं करेगी ऐसी है कि अपने आप में एक महत्वपूर्ण सीपीयू लोड हो जाते हैं),

  1. कंप्यूट CPU समय की राशि आपके धागा पिछली बार अपने थ्रॉटलिंग समारोह के बाद से इस्तेमाल कहा जाता था (मैं इस डीसीपीयू को कॉल करूंगा)। आप अपने धागे को निष्पादित करने की मात्रा प्राप्त करने के लिए GetThreadTimes() एपीआई का उपयोग कर सकते हैं।
  2. पिछली बार आपके थ्रॉटलिंग फ़ंक्शन को कॉल करने के बाद वास्तविक समय की मात्रा की गणना करें (मैं इस डीक्लॉक को कॉल करूंगा)।
  3. डीसीपीयू/डीक्लॉक प्रतिशत CPU उपयोग (एक सीपीयू का) है। यदि यह आपकी इच्छा से अधिक है, तो नींद का समय बढ़ाएं, यदि कम हो, तो नींद का समय कम करें।
  4. आपके धागे को गणना के समय के लिए सोएं।

आपके वॉचडॉग CPU उपयोग की गणना कैसे करता है, इस पर निर्भर करता है कि सिस्टम के कितने सीपीयू हैं, यह जानने के लिए आप GetProcessAffinityMask() का उपयोग करना चाहेंगे। डीसीपीयू/(डीक्लॉक * सीपीयू) उपलब्ध कुल CPU समय का प्रतिशत है।

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

+0

यदि आपका लक्ष्य सीपीयू समय बर्बाद करने से बचाना है, तो एक सस्ता हेरिस्टिक शायद बेहतर विकल्प है। आपके थ्रेड के लिए उच्च सिस्टम लोड के तहत खुद को भूखा होने के लिए कितनी समस्या है, इस पर निर्भर करता है कि आप * बस * दीवार की घड़ी के समय की जांच कर सकते हैं। X86 पर, यह बहुत सस्ता है, क्योंकि 'rdtsc' के आधार पर समय फ़ंक्शन को कर्नेल मोड में प्रवेश करने की भी आवश्यकता नहीं है। कई सिस्टम कॉल करना भी 'एन' पुनरावृत्तियों को केवल एक बनाने से भी बदतर है, जब तक कि यह आपको बहुत से' एन' 'बढ़ाने में सक्षम न हो और फिर भी आप जो व्यवहार चाहते हैं उसे प्राप्त करें। –

2

मैं आप क्या चाहते हैं के किसी भी पार मंच तरीका (या किसी भी गारंटी तरीका पूर्ण विराम) के बारे में सोच नहीं सकते हैं, लेकिन जैसा कि आप GetTickCount उपयोग कर रहे हैं शायद आप क्रॉस प्लेटफॉर्म :)

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

संपादित करें: मैं Bernard से सहमत हूं, इसलिए मुझे लगता है कि धागे की बजाय एक प्रक्रिया अधिक उपयुक्त हो सकती है लेकिन यह आपके उद्देश्यों के अनुरूप नहीं हो सकती है।

4

लिनक्स पर, आप अच्छे() के साथ थ्रेड की शेड्यूलिंग प्राथमिकता बदल सकते हैं।

+0

अन्य प्लेटफार्मों में समान विशेषताएं हैं, यह भी देखें: https://stackoverflow.com/questions/18884510/portable-way-of-setting-stdthread-priority-in-c11 मुझे लगता है कि यह समस्या का एक अच्छा समाधान हो सकता है, यद्यपि विभिन्न अर्थशास्त्र के साथ - यानी 50% सीपीयू खपत गारंटी – milianw

2

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

यह मुझे लगता है जैसे समस्या वॉचडॉग प्रक्रिया है।

यदि आपका पृष्ठभूमि कार्य सीपीयू-बाध्य है तो आप इसे अपने काम के लिए सभी अप्रयुक्त CPU समय लेना चाहते हैं।

शायद आपको वॉचडॉग प्रोग्राम को ठीक करने पर विचार करना चाहिए?

+1

एक निष्क्रिय सीपीयू चाहते हैं यह बहुत उचित है। हो सकता है कि आप कुछ गणना करना चाहते हैं लेकिन इस पर ध्यान न दें कि यह कितना तेज़ हो जाता है, जब तक यह आपके लैपटॉप पर सीपीयू प्रशंसक को स्पिन नहीं करता है। – Ringding

0

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