Std :: system_clock और std :: stabil_clock के बीच अंतर?


97

बीच क्या अंतर है std::system_clockऔर std::steady_clock? (एक उदाहरण मामला जो विभिन्न परिणामों / व्यवहारों को स्पष्ट करेगा, महान होगा)।

मेरा लक्ष्य ठीक काम करता है (एक बेंचमार्क की तरह) के निष्पादन के समय को मापने के लिए है, तो क्या के बीच सबसे अच्छा विकल्प होगा std::system_clock, std::steady_clockऔर std::high_resolution_clock?


9
शुरू करने के लिए, system_clock स्थिर नहीं हो सकता है।
जेम्स मैकनेलिस

12
@CharlesSalvia मैं अन्य प्लेटफार्मों के लिए बात नहीं कर सकता, लेकिन system_clockविंडोज पर स्थिर नहीं है। विंडोज पर, सिस्टम समय को किसी भी पर्याप्त विशेषाधिकार प्राप्त उपयोगकर्ता द्वारा किसी भी मनमाने मूल्य के लिए बदल दिया जा सकता है। इसके अतिरिक्त, समय सिंक्रोनाइज़ेशन सेवा आवश्यकता होने पर सिस्टम समय को पीछे की ओर समायोजित कर सकती है। मुझे उम्मीद है कि अधिकांश अन्य प्लेटफार्मों में समान विशेषताएं हैं जो सिस्टम समय के समायोजन की अनुमति देती हैं।
जेम्स मैकनेलिस

3
@Charles: मुझे पता है कि ज्यादातर POSIX बॉक्स उसी तरह प्रभावित होते हैं और यदि उपयोगकर्ता समय बदलता है तो उनका समय बदल जाएगा।
बिली ओपल

5
इस सवाल का वीडियो जवाब: youtube.com/watch?v=P32hvk8b13M&t=48m44s
हावर्ड हिनान्ट

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

जवाबों:


71

N3376 से:

20.11.7.1 [time.clock.system] / 1:

क्लास की वस्तुएं system_clockसिस्टम-वाइड रीयलटाइम घड़ी से दीवार घड़ी समय का प्रतिनिधित्व करती हैं।

20.11.7.2 [time.clock.steady] / 1:

कक्षा की वस्तुएँ उन steady_clockघड़ियों का प्रतिनिधित्व करती हैं जिनके लिए time_pointभौतिक समय के अग्रिमों के रूप में मूल्यों में कभी कमी नहीं होती है और जिसके time_pointलिए वास्तविक समय के सापेक्ष स्थिर दर पर अग्रिम के मूल्य होते हैं । यही है, घड़ी समायोजित नहीं हो सकती है।

20.11.7.3 [time.clock.hires] / 1:

कक्षा की वस्तुएँ high_resolution_clockसबसे छोटी टिक अवधि के साथ घड़ियों का प्रतिनिधित्व करती हैं। high_resolution_clockके लिए एक पर्याय हो सकता है system_clockया steady_clock

उदाहरण के लिए, सिस्टम वाइड क्लॉक दिन के समय की बचत के समय जैसी किसी चीज से प्रभावित हो सकता है, जिस बिंदु पर भविष्य में कुछ बिंदु पर सूचीबद्ध वास्तविक समय वास्तव में अतीत का समय हो सकता है। (उदा। अमेरिका में, गिरने के समय में एक घंटा पीछे चला जाता है, इसलिए उसी घंटे को "दो बार" अनुभव किया जाता है) हालांकि, steady_clockऐसी चीजों से प्रभावित होने की अनुमति नहीं है।

इस मामले में "स्थिर" सोचने का एक और तरीका 20.11.3 [time.clock.req] / 2 की तालिका में परिभाषित आवश्यकताओं में है:

तालिका 59 में C1और C2घड़ी प्रकार निरूपित करें। t1और t2वे मान लौटाए जाते हैं C1::now()जहाँ कॉल लौटने t1से पहले t2कॉलिंग वापस होती है और ये दोनों कॉल पहले होते हैं C1::time_point::max()। [नोट: इसका मतलब यह है C1कि चारों ओर लपेट नहीं किया t1और t2। ध्यान दें]

अभिव्यक्ति: C1::is_steady
रिटर्न: const bool
परिचालन शब्दार्थ: trueअगर t1 <= t2हमेशा सच होता है और घड़ी की टिक के बीच का समय स्थिर होता है, अन्यथा false

यह सभी मानक उनके मतभेदों पर है।

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


1
@ घर: मानक में इंगित करने के लिए देखभाल जहां मामला है? यह स्पष्ट रूप से विपरीत संकेत देता है।
बिली ओपल

9
@Charles: इसके अलावा, POSIX समय "स्थिर" नहीं है - यदि उपयोगकर्ता अपने कंप्यूटर पर समय सेटिंग बदलता है तो POSIX समय बदल जाएगा। यदि आप एक अंडा पका रहे हैं, और एक टाइमर की आवश्यकता है जो 4 मिनट तक रहता है, तो आपको वर्तमान समय में परिवर्तन होने पर भी इसे 4 मिनट तक की आवश्यकता होगी। अगर आपको 5 तारीख को 3 बजे मीटिंग के लिए टाइमर सेट मिल गया है, तो आपको स्थानीय समय बदलने पर उस टाइमर को बदलने की आवश्यकता है। इसलिए steady_clockऔर system_clockयहाँ के बीच का अंतर ।
बिली ओपल

1
@ 5gon: कुछ भी नहीं है कि system_clockUTC होना चाहिए ।
बिली ओनेल

1
@CharlesSalvia कृपया ध्यान दें कि चूंकि POSIX का समय UTC से बंधा हुआ है, और UTC में लीप सेकंड (cf. en.wikipedia.org/wiki/Unix_time#Leap_seconds ) है। इसका मतलब है कि भले ही मशीन पर समय समायोजित न हो, लेकिन C / POSIX समय गैर-मोनोटोनिक हो सकता है।
माइकल श्लोट्के-लक्पर

3
UPDATE (विजुअल स्टूडियो 2015) स्थिर_कॉल का कार्यान्वयन बदल गया है [.....] स्थिर_क्लॉक अब क्वेरीपेरफॉर्मेंस एनकाउंटर () पर आधारित है और high_resolution_clock अब static_clock के लिए एक प्रकार है। Msdn.microsoft.com/en-us/library/hh874757.aspx
felix-b

47

बिली ने आईएसओ सी ++ मानक के आधार पर एक शानदार जवाब दिया, जिससे मैं पूरी तरह सहमत हूं। हालाँकि कहानी का एक और पक्ष है - वास्तविक जीवन। ऐसा लगता है कि अभी लोकप्रिय संकलक के कार्यान्वयन में उन घड़ियों के बीच वास्तव में कोई अंतर नहीं है:

gcc 4.8:

#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
   ...
#else
  typedef system_clock steady_clock;
#endif
  typedef system_clock high_resolution_clock;

विजुअल स्टूडियो 2012:

class steady_clock : public system_clock
{   // wraps monotonic clock
public:
  static const bool is_monotonic = true;    // retained
  static const bool is_steady = true;
};

typedef system_clock high_resolution_clock;

यदि आप केवल जाँच करके is_steadyऔर उसके अनुसार व्यवहार करते हैं तो gcc के मामले में आप जाँच कर सकते हैं । हालाँकि VS2012 यहाँ थोड़ा धोखा देने लगता है :-)

यदि आपको उच्च परिशुद्धता वाली घड़ी की आवश्यकता है, तो मैं अब आपकी अपनी घड़ी लिखने की सलाह देता हूं जो C ++ 11 आधिकारिक घड़ी इंटरफ़ेस के अनुरूप है और कार्यान्वयन को पकड़ने के लिए प्रतीक्षा करें। यह आपके कोड में सीधे ओएस विशिष्ट एपीआई का उपयोग करने से बेहतर होगा। विंडोज के लिए आप ऐसा कर सकते हैं:

// Self-made Windows QueryPerformanceCounter based C++11 API compatible clock
struct qpc_clock {
  typedef std::chrono::nanoseconds                       duration;      // nanoseconds resolution
  typedef duration::rep                                  rep;
  typedef duration::period                               period;
  typedef std::chrono::time_point<qpc_clock, duration>   time_point;
  static bool is_steady;                                                // = true
  static time_point now()
  {
    if(!is_inited) {
      init();
      is_inited = true;
    }
    LARGE_INTEGER counter;
    QueryPerformanceCounter(&counter);
    return time_point(duration(static_cast<rep>((double)counter.QuadPart / frequency.QuadPart *
                                                period::den / period::num)));
  }

private:
  static bool is_inited;                                                // = false
  static LARGE_INTEGER frequency;
  static void init()
  {
    if(QueryPerformanceFrequency(&frequency) == 0)
      throw std::logic_error("QueryPerformanceCounter not supported: " + std::to_string(GetLastError()));
  }
};

लिनक्स के लिए यह और भी आसान है। बस clock_gettimeऊपर दिए गए कोड के मैन पेज को पढ़ें और संशोधित करें।


19
वीसी ++ 2012 के कार्यान्वयन को एमएस के मानक पुस्तकालय अनुचर द्वारा बग के रूप में स्वीकार किया गया है।
०१:१६ बजे ildjarn

5
रुचि रखने वालों के लिए, यह उस बग का एक लिंक है
बेन वोइगट

1
बूस्ट QueryPerformanceCounter का उपयोग करता है, इसलिए बढ़ावा देने का उपयोग करते हुए :: क्रोनो विजुअल स्टूडियो 14 जारी होने तक इस बग का एक अच्छा समाधान है
मोहम्मद अल-नकीब

और यहाँ POSIX कॉल करने वालों को GCC 5.3.0 पर आगे किया गया है: stackoverflow.com/a/36700301/895245
Ciro Santilli 郝海东 OS OS 六四

19

जीसीसी 5.3.0 कार्यान्वयन

C ++ stdlib GCC स्रोत के अंदर है:

  • high_resolution_clock के लिए एक उपनाम है system_clock
  • system_clock निम्नलिखित में से पहले के लिए उपलब्ध है:
    • clock_gettime(CLOCK_REALTIME, ...)
    • gettimeofday
    • time
  • steady_clock निम्नलिखित में से पहले के लिए उपलब्ध है:
    • clock_gettime(CLOCK_MONOTONIC, ...)
    • system_clock

फिर CLOCK_REALTIMEबनाम CLOCK_MONOTONICसमझाया जाता है: CLOCK_REALTIME और CLOCK_MONOTONIC में अंतर?


2

हो सकता है, सबसे महत्वपूर्ण अंतर यह तथ्य है कि शुरुआती बिंदु std::chrono:system_clock1.1.1970 है, जिसे UNIX-epoch कहा जाता है। दूसरी ओर, std::chrono::steady_clockआमतौर पर आपके पीसी के बूट समय के लिए और यह अंतराल को मापने के लिए सबसे उपयुक्त है।

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