2008-09-26 15 views
7

Win32 में, एक अद्वितीय सीपीयू चक्र गणना या ऐसा कुछ ऐसा करने का कोई तरीका है जो एकाधिक प्रक्रियाओं/भाषाओं/सिस्टम/आदि के लिए समान होगा।मैं Win32 में सीपीयू चक्र गणना कैसे प्राप्त करूं?

मैं कुछ लॉग फाइल बना रहा हूं, लेकिन क्योंकि हम .NET रनटाइम होस्ट कर रहे हैं कई लॉगफ़ाइल का उत्पादन किया है, और मैं दूसरे के प्रवेश करने के लिए से फोन कर से बचने के लिए चाहते हैं। इस तरह, मैं सोच रहा था कि मैं केवल दो फाइलें उत्पन्न करूंगा, उन्हें गठबंधन करूँगा, और फिर उन्हें सॉर्ट करें, क्रॉस-वर्ल्ड कॉल से जुड़ी एक सुसंगत समयरेखा प्राप्त करने के लिए।

हालांकि, GetTickCount हर कॉल के लिए वृद्धि नहीं करता है, तो यह है कि विश्वसनीय नहीं है। क्या कोई बेहतर संख्या है, ताकि सॉर्ट करते समय मुझे सही क्रम में कॉल मिलें?


संपादित: @Greg कि मुझे QueryPerformanceCounter को ट्रैक, जो चाल किया था पर डाल के लिए धन्यवाद।

उत्तर

8

आप RDTSC सीपीयू अनुदेश (यह मानते हुए 86) का उपयोग कर सकते हैं। यह निर्देश सीपीयू चक्र काउंटर देता है, लेकिन ध्यान रखें कि यह अपने अधिकतम मूल्य में बहुत तेज़ी से बढ़ेगा, और फिर 0 पर रीसेट हो जाएगा। विकिपीडिया आलेख का उल्लेख है, तो आप QueryPerformanceCounter फ़ंक्शन का उपयोग करके बेहतर हो सकते हैं।

12

Heres an interesting article! RDTSC उपयोग करने के लिए नहीं है, लेकिन बजाय QueryPerformanceCounter उपयोग करने के लिए कहते हैं।

निष्कर्ष:

नियमित वर्ष timeGetTime() का उपयोग समय ऐसा करने के लिए कई Windows- आधारित ऑपरेटिंग सिस्टम पर विश्वसनीय है क्योंकि सिस्टम टाइमर के विवरण का स्तर 10-15 मिलीसेकेंड के रूप में उच्च हो सकता है नहीं है , जिसका अर्थ है कि timeGetTime() केवल 10-15 मिलीसेकंड के लिए सटीक है। [ध्यान दें कि उच्च ग्रॅन्युलरिटी एनटी-आधारित विंडोज एनटी, 2000, और एक्सपी जैसे ऑपरेशन सिस्टम पर होती है। Windows 95 और 98 जाते हैं काफी बेहतर विवरण के स्तर को पाने के लिए 1-5 चारों ओर एमएस।]

हालांकि, अगर आप ( अंत में और timeEndPeriod(1)) अपने कार्यक्रम की शुरुआत में timeBeginPeriod(1) फोन, timeGetTime() आमतौर पर होगा 1-2 मिलीसेकंड, के लिए सटीक बन गया है और आपको सटीक समय की जानकारी अत्यंत प्रदान करेगा।

Sleep() इसी प्रकार व्यवहार करता है; समय की लंबाई कि Sleep() वास्तव में के लिए सोता timeGetTime() की विस्तृत रूप से हाथ में हाथ जाता है, तो बाद timeBeginPeriod(1) एक बार बुला, Sleep(1) वास्तव में 1-2 मिलीसेकेंड, 2-3 के लिए Sleep(2) के लिए सोने जाएगा, और तो पर (वृद्धि में 10-15 एमएस जितना अधिक) में सोने की बजाय)।

उच्च परिशुद्धता समय (उप millisecond सटीकता) के लिए, आप शायद विधानसभा स्मरक RDTSC का उपयोग कर, क्योंकि यह कठिन ठीक करना है से बचने के लिए चाहता हूँ; इसके बजाय, QueryPerformanceFrequency और QueryPerformanceCounter, जो 10 माइक्रोसॉन्ड (0.00001 सेकंड) से कम सटीक हैं, का उपयोग करें।

सरल समय के लिए, दोनों timeGetTime और QueryPerformanceCounter, अच्छी तरह से काम और QueryPerformanceCounter स्पष्ट रूप से अधिक सटीक है। हालांकि, अगर आप "समय रुक जाता है" (जैसे फ़्रेमरेट सीमित करने के लिए आवश्यक होते हैं) को किसी भी तरह का क्या करने की जरूरत है, तो आप एक पाश QueryPerformanceCounter बुला में बैठे, यह एक निश्चित तक पहुँचने के लिए के लिए इंतजार की सावधान रहना चाहिए मूल्य; यह आपके प्रोसेसर का 100% खाएगा। इसके बजाय, ((1) पहले! timeBeginPeriod मत भूलना) जब भी आप समय से अधिक 1 एमएस पारित करने के लिए, और उसके बाद की जरूरत है केवल QueryPerformanceCounter दर्ज एक संकर योजना, जहां फोन नींद (1) पर विचार 100% -busy पाश पिछले < 1/देरी की जरूरत के एक दूसरे की 1000 वीं बंद खत्म करने के लिए। यह आप बहुत कम CPU उपयोग के साथ अति सटीक देरी दे देंगे (10 माइक्रोसेकंड करने के लिए सही),। उपरोक्त कोड देखें।

+3

timeBeginPeriod() से बचें; यह सिस्टम-व्यापी शेड्यूलर को प्रभावित करता है और ऊर्जा की बचत के साथ समस्याएं पैदा कर सकता है। – MSalters

1

GetTickCount का उपयोग करें और लॉग फ़ाइलों को मर्ज करते समय एक और काउंटर जोड़ें। आपको अलग-अलग लॉग फ़ाइलों के बीच सही अनुक्रम नहीं देगा, लेकिन कम से कम प्रत्येक फ़ाइल से सभी लॉग सही क्रम में रखेंगे।

+2

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

2

सिस्टम। डायग्नोस्टिक्स .topwatch.GetTimestamp() एक समय मूल के बाद से CPU चक्र की संख्या लौटाता है (शायद जब कंप्यूटर शुरू होता है, लेकिन मुझे यकीन नहीं है) और मैंने इसे कभी भी 2 कॉल के बीच नहीं बढ़ाया है।

CPU चक्र प्रत्येक कंप्यूटर के लिए विशिष्ट है ताकि आप इसे इस्तेमाल नहीं कर सकते 2 कंप्यूटर के बीच लॉग फ़ाइल विलय करने के लिए किया जाएगा।

+0

धन्यवाद, मैं केवल उसी कंप्यूटर पर उसी कंप्यूटर पर उत्पादित फ़ाइलों को मर्ज करने जा रहा हूं, जिससे यह काम करेगा। अब मुझे यह पता लगाने की जरूरत है कि वास्तव में कौन सी विधि कॉल करती है :) –

2

RDTSC उत्पादन वर्तमान कोर की घड़ी आवृत्ति है, जो आधुनिक CPUs के लिए न तो निरंतर है और न ही, एक मल्टीकोर मशीन में, संगत है पर निर्भर हो सकता।

प्रणाली समय का उपयोग करें, और कई सिस्टम से फ़ीड के साथ काम करता है, तो एक NTP समय स्रोत का उपयोग करें। आप इस तरह विश्वसनीय, लगातार समय रीडिंग प्राप्त कर सकते हैं; अगर ओवरहेड आपके उद्देश्यों के लिए बहुत अधिक है, तो HPET का उपयोग करके समय समाप्त हो गया है क्योंकि आखिरी ज्ञात विश्वसनीय समय पढ़ने अकेले एचपीईटी का उपयोग करने से बेहतर है।