ANSI C का उपयोग करके मिलीसेकंड में समय कैसे मापें?


127

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


4
सटीक और सटीकता के बीच अंतर पर ध्यान दें। सेकंड में समय लेकर और 1000 से गुणा करके आप मिलीसेकंड परिशुद्धता के साथ एक समय प्राप्त कर सकते हैं , लेकिन इसका कोई फायदा नहीं है। एमएस परिशुद्धता कार्यों में आवश्यक रूप से एमएस सटीकता नहीं है - हालांकि वे आम तौर पर 1 एस सटीकता से बेहतर करते हैं।
स्टीव जेसोप

2
सरल उत्तर नहीं है, एएनएसआई सी मिलीसेकंड सटीक या बेहतर का समर्थन नहीं करता है। अधिक जटिल उत्तर इस बात पर निर्भर करता है कि आप क्या करने की कोशिश कर रहे हैं - स्पष्ट रूप से पूरा क्षेत्र एक दुःस्वप्न है - भले ही आप व्यापक रूप से उपलब्ध पॉज़िक्स फ़ंक्शन का उपयोग करने की अनुमति दें। आप "उपाय" शब्द का उपयोग करते हैं, इसलिए मुझे लगता है कि आप "दीवार घड़ी" समय के बजाय एक अंतराल में रुचि रखते हैं। लेकिन क्या आप अपनी प्रक्रिया द्वारा निरपेक्ष समय अवधि या सीपीयू उपयोग को मापने का प्रयास कर रहे हैं?
डिपस्टिक

2
बस SOF से कहना चाहता था कि
उसने

जवाबों:


92

कोई एएनएसआई सी फ़ंक्शन नहीं है जो 1 सेकंड के समय के रिज़ॉल्यूशन लेकिन पोसिक्स फ़ंक्शन से बेहतर प्रदान करता है gettimeofday माइक्रोसेकंड रिज़ॉल्यूशन प्रदान करता है। घड़ी फ़ंक्शन केवल उस समय की मात्रा को मापता है जो एक प्रक्रिया ने निष्पादन में खर्च किया है और कई प्रणालियों पर सटीक नहीं है।

आप इस फ़ंक्शन का उपयोग इस तरह कर सकते हैं:

struct timeval tval_before, tval_after, tval_result;

gettimeofday(&tval_before, NULL);

// Some code you want to time, for example:
sleep(1);

gettimeofday(&tval_after, NULL);

timersub(&tval_after, &tval_before, &tval_result);

printf("Time elapsed: %ld.%06ld\n", (long int)tval_result.tv_sec, (long int)tval_result.tv_usec);

यह Time elapsed: 1.000870मेरी मशीन पर लौटता है ।


30
थोड़ा सा चेतावनी: gettimeofday () मोनोटोनिक नहीं है, जिसका अर्थ है कि यह चारों ओर कूद सकता है (और यहां तक ​​कि पीछे की ओर भी जा सकता है), उदाहरण के लिए, आपकी मशीन नेटवर्क टाइम सर्वर या किसी अन्य समय स्रोत के साथ सिंक्रनाइज़ेशन रखने का प्रयास कर रही है।
डिपस्टिक

3
सटीक होना: आईएसओ सी 99 में (जो मुझे लगता है कि एएनएसआई सी के साथ इस हिस्से में संगत है) किसी भी समय संकल्प की गारंटी नहीं है । (आईएसओ सी 99, 7.23.1p4)
रोलैंड इलिग

6
यह ध्यान देने योग्य है कि timeval::tv_usecयह हमेशा एक सेकंड के नीचे होता है, यह लूपिंग होता है। 1 सेकंड से अधिक समय के अंतर को लेने के लिए, आपको चाहिए:long usec_diff = (e.tv_sec - s.tv_sec)*1000000 + (e.tv_usec - s.tv_usec);
अलेक्जेंडर मालाखोव

4
@ डिपस्टिक: लेकिन ध्यान दें कि उदाहरण के लिए जब तक आप स्पष्ट रूप से ऐसा करने के लिए नहीं कहते हैं तब तक एनटीपी आपकी घड़ी को पीछे की ओर नहीं ले जाता है।
thejh

1
@AlexanderMalakhov समय घटाव तर्क timersubसमारोह के अंदर बिगड़ा हुआ है। हम tval_resultमानों (tv_sec और tv_usec) का उपयोग कर सकते हैं -जैसा है।
x4444

48
#include <time.h>
clock_t uptime = clock() / (CLOCKS_PER_SEC / 1000);

CLOCKS_PER_SEC कई प्रणालियों पर 1000000 पर सेट है। इससे पहले कि आप इसका इस फैशन में उपयोग करें, सुनिश्चित करने के लिए इसके मूल्य को प्रिंट करें।
ysap २ y

16
चूंकि यह प्रति सेकंड घड़ियां है, इससे कोई फर्क नहीं पड़ता कि यह क्या मूल्य है, घड़ी से परिणामी मूल्य () / CLOCKS_PER_SEC सेकंड में होगा (कम से कम यह होना चाहिए)। 1000 से विभाजित होने से वह मिलीसेकंड में बदल जाता है।
डेविड यंग

14
सी संदर्भ नियमावली के अनुसार, घड़ी का मान लगभग 36 मिनट से शुरू हो सकता है। यदि आप एक लंबी गणना को माप रहे हैं तो आपको इसके बारे में पता होना चाहिए।
साइबरस्कूल

4
यह भी सावधान रहें कि पूर्णांक विभाजन CLOCKS_PER_SEC / 1000संभवतः CLOCKS_PER_SECअक्षम हो सकता है जो अंतिम परिणाम को प्रभावित कर सकता है (हालांकि मेरे अनुभव में हमेशा 1000 का गुणक रहा है)। अक्षमता (1000 * clock()) / CLOCKS_PER_SECको कम करने के लिए अतिसंवेदनशील है, लेकिन दूसरी तरफ अतिप्रवाह के लिए अतिसंवेदनशील है। बस कुछ मुद्दों पर विचार करने के लिए।
कॉर्नस्टॉक

4
क्या यह cpu समय नहीं मापता है और दीवार समय नहीं है?
krs013

28

मैं हमेशा घड़ी_गेटाइम () फ़ंक्शन का उपयोग करता हूं, CLOCK_MONOTONIC घड़ी से समय लौटाता हूं। लौटाया गया समय, सेकंड और नैनोसेकंड में समय की मात्रा है, क्योंकि अतीत में कुछ अनिर्दिष्ट बिंदु, जैसे कि युग के सिस्टम स्टार्टअप।

#include <stdio.h>
#include <stdint.h>
#include <time.h>

int64_t timespecDiff(struct timespec *timeA_p, struct timespec *timeB_p)
{
  return ((timeA_p->tv_sec * 1000000000) + timeA_p->tv_nsec) -
           ((timeB_p->tv_sec * 1000000000) + timeB_p->tv_nsec);
}

int main(int argc, char **argv)
{
  struct timespec start, end;
  clock_gettime(CLOCK_MONOTONIC, &start);

  // Some code I am interested in measuring 

  clock_gettime(CLOCK_MONOTONIC, &end);

  uint64_t timeElapsed = timespecDiff(&end, &start);
}

5
clock_gettime () एएनएसआई सी नहीं है
PowerApp101

1
इसके अलावा CLOCK_MONOTONIC कई प्रणालियों (कई लिनक्स प्लेटफार्मों सहित) पर लागू नहीं है।
डिपस्टिक

2
@ PowerApp101 ऐसा करने का कोई अच्छा / मजबूत ANSI C तरीका नहीं है। अन्य जवाबों में से कई ANCI C. के बजाय POSIX पर निर्भर करते हैं। कहा जा रहा है, मेरा मानना ​​है कि आज। @ डिपस्टिक आज, मेरा मानना ​​है कि अधिकांश आधुनिक प्लेटफार्म [उद्धरण वांछित] समर्थन करते हैं clock_gettime(CLOCK_MONOTONIC, ...)और यहां तक ​​कि फीचर टेस्ट मैक्रो भी है _POSIX_MONOTONIC_CLOCK
omninonsense

22

पोर्टेबल समाधान लागू करना

जैसा कि यहां पहले ही उल्लेख किया गया था कि समय मापन समस्या के लिए पर्याप्त सटीकता के साथ कोई उचित एएनएसआई समाधान नहीं है, मैं उन तरीकों के बारे में लिखना चाहता हूं कि कैसे एक पोर्टेबल और, यदि संभव हो तो, एक उच्च-रिज़ॉल्यूशन समय मापन समाधान।

मोनोटोनिक घड़ी बनाम समय टिकटों

आम तौर पर बोलने के समय मापने के दो तरीके हैं:

  • मोनोटोनिक घड़ी;
  • वर्तमान (तारीख) समय टिकट।

पहले वाला एक मोनोटोनिक क्लॉक काउंटर (कभी-कभी इसे टिक काउंटर कहा जाता है) का उपयोग करता है, जो एक पूर्वनिर्धारित आवृत्ति के साथ टिकों की गिनती करता है, इसलिए यदि आपके पास एक टिक मूल्य है और आवृत्ति ज्ञात है, तो आप आसानी से टिक को बीता हुआ समय में बदल सकते हैं। यह वास्तव में गारंटी नहीं है कि एक मोनोटोनिक घड़ी किसी भी तरह से वर्तमान सिस्टम समय को दर्शाती है, यह सिस्टम स्टार्टअप के बाद से टिकों की गिनती भी कर सकती है। लेकिन यह गारंटी देता है कि सिस्टम राज्य की परवाह किए बिना एक घड़ी हमेशा बढ़ती हुई शैली में चलती है। आमतौर पर आवृत्ति एक हार्डवेयर उच्च-रिज़ॉल्यूशन स्रोत से जुड़ी होती है, इसीलिए यह एक उच्च सटीकता प्रदान करता है (हार्डवेयर पर निर्भर करता है, लेकिन अधिकांश आधुनिक हार्डवेयर में उच्च-रिज़ॉल्यूशन क्लॉक स्रोतों के साथ कोई समस्या नहीं है)।

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

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

पतन की रणनीति

पोर्टेबल समाधान को लागू करते समय यह एक गिरावट की रणनीति पर विचार करने के लिए लायक है: यदि उपलब्ध है और सिस्टम में कोई मोनोटोनिक घड़ी नहीं है, तो समय स्टैम्प दृष्टिकोण के लिए उपलब्ध होने पर एक मोनोटोनिक घड़ी का उपयोग करें।

खिड़कियाँ

विंडोज पर समय मापन के बारे में MSDN पर उच्च-रिज़ॉल्यूशन समय टिकटों को प्राप्त करने के लिए एक महान लेख है, जिसमें उन सभी विवरणों का वर्णन है जो आपको सॉफ़्टवेयर और हार्डवेयर समर्थन के बारे में जानने की आवश्यकता हो सकती है। विंडोज पर एक उच्च परिशुद्धता समय टिकट प्राप्त करने के लिए आपको चाहिए:

  • क्वेरी टाइमर आवृत्ति (प्रति सेकंड टिक्स) QueryPerformanceFrequency के साथ :

    LARGE_INTEGER tcounter;
    LARGE_INTEGER freq;    
    
    if (QueryPerformanceFrequency (&tcounter) != 0)
        freq = tcounter.QuadPart;

    टाइमर की आवृत्ति सिस्टम बूट पर तय की गई है, इसलिए आपको इसे केवल एक बार प्राप्त करने की आवश्यकता है।

  • क्वेरी के साथ मौजूदा टिक वैल्यू को क्वेरीपेरफॉर्मेंस एनकाउंटर के लिए क्वेरी करें :

    LARGE_INTEGER tcounter;
    LARGE_INTEGER tick_value;
    
    if (QueryPerformanceCounter (&tcounter) != 0)
        tick_value = tcounter.QuadPart;
  • स्केल को बीता हुआ समय, अर्थात माइक्रोसेकंड तक:

    LARGE_INTEGER usecs = (tick_value - prev_tick_value) / (freq / 1000000);

Microsoft के अनुसार आपको ज्यादातर मामलों में Windows XP और बाद के संस्करणों में इस दृष्टिकोण से कोई समस्या नहीं होनी चाहिए। लेकिन आप विंडोज पर दो फॉलबैक सॉल्यूशंस का भी इस्तेमाल कर सकते हैं:

  • GetTickCount सिस्टम शुरू होने के बाद से मिलीसेकंड की संख्या प्रदान करता है। यह हर 49.7 दिन में लपेटता है, इसलिए लंबे अंतराल को मापने में सावधानी बरतें।
  • GetTickCount64 64-बिट संस्करण है GetTickCount, लेकिन यह Windows Vista और इसके बाद के संस्करण से उपलब्ध है।

OS X (macOS)

OS X (macOS) की अपनी स्वयं की मच निरपेक्ष समय इकाइयाँ हैं जो एक मोनोटोनिक घड़ी का प्रतिनिधित्व करती हैं। शुरू करने का सबसे अच्छा तरीका ऐप्पल का लेख तकनीकी क्यू एंड ए क्यूए 1398: मच एब्सोल्यूट टाइम इकाइयाँ हैं (जो कोड उदाहरणों के साथ) बताता है कि मोनोटोनिक टिक पाने के लिए मच-विशिष्ट एपीआई का उपयोग कैसे करें। इसके बारे में एक स्थानीय सवाल यह भी है कि मैक ओएस एक्स में घड़ी_गेटटाइम विकल्प कहा जाता है जो अंत में आपको थोड़ा भ्रमित कर सकता है कि संभावित मूल्य अतिप्रवाह के साथ क्या करना है क्योंकि काउंटर आवृत्ति का उपयोग अंश और हर के रूप में किया जाता है। तो, एक छोटा सा उदाहरण कि कैसे बीते हुए समय को प्राप्त करें:

  • घड़ी आवृत्ति अंश और हर प्राप्त करें:

    #include <mach/mach_time.h>
    #include <stdint.h>
    
    static uint64_t freq_num   = 0;
    static uint64_t freq_denom = 0;
    
    void init_clock_frequency ()
    {
        mach_timebase_info_data_t tb;
    
        if (mach_timebase_info (&tb) == KERN_SUCCESS && tb.denom != 0) {
            freq_num   = (uint64_t) tb.numer;
            freq_denom = (uint64_t) tb.denom;
        }
    }

    आपको केवल एक बार ऐसा करने की आवश्यकता है।

  • वर्तमान टिक वैल्यू के साथ क्वेरी करें mach_absolute_time:

    uint64_t tick_value = mach_absolute_time ();
  • स्केल को बीता हुआ समय, अर्थात् माइक्रोसेकंड के लिए, पहले से ही अंश और हर का उपयोग करके:

    uint64_t value_diff = tick_value - prev_tick_value;
    
    /* To prevent overflow */
    value_diff /= 1000;
    
    value_diff *= freq_num;
    value_diff /= freq_denom;

    अतिप्रवाह को रोकने के लिए मुख्य विचार यह है कि अंश और हर का उपयोग करने से पहले टिक्सेस को वांछित सटीकता तक स्केल किया जाए। जैसा कि प्रारंभिक टाइमर संकल्प नैनोसेकंड में है, हम इसे 1000माइक्रोसेकंड प्राप्त करने के लिए विभाजित करते हैं । आप क्रोमियम के time_mac.c में उपयोग किए गए समान दृष्टिकोण को पा सकते हैं । अगर आपको वास्तव में नैनोसेकंड सटीकता की आवश्यकता है, तो पढ़ने पर विचार करें कि मैं कैसे बिना ओवरफ्लो किए mach_absolute_time का उपयोग कर सकता हूं?

लिनक्स और यूनिक्स

clock_gettimeकॉल किसी भी POSIX के अनुकूल प्रणाली पर अपने सबसे अच्छा तरीका है। यह अलग-अलग घड़ी स्रोतों से समय की क्वेरी कर सकता है, और जिसकी हमें आवश्यकता है CLOCK_MONOTONIC। सभी प्रणालियाँ जिनके पास clock_gettimeसमर्थन नहीं है CLOCK_MONOTONIC, इसलिए सबसे पहले आपको इसकी उपलब्धता की जाँच करनी होगी:

  • अगर _POSIX_MONOTONIC_CLOCKमूल्य को परिभाषित किया जाता है >= 0तो इसका मतलब है कि CLOCK_MONOTONICयह उपलब्ध है;
  • यदि _POSIX_MONOTONIC_CLOCKइसे परिभाषित किया गया है, 0तो इसका मतलब है कि आपको अतिरिक्त जांच करनी चाहिए कि क्या यह रनटाइम पर काम करता है, मैं उपयोग करने का सुझाव देता हूं sysconf:

    #include <unistd.h>
    
    #ifdef _SC_MONOTONIC_CLOCK
    if (sysconf (_SC_MONOTONIC_CLOCK) > 0) {
        /* A monotonic clock presents */
    }
    #endif
  • अन्यथा एक मोनोटोनिक घड़ी समर्थित नहीं है और आपको फ़ॉलबैक रणनीति (नीचे देखें) का उपयोग करना चाहिए।

उपयोग clock_gettimeसीधे आगे है:

  • समय मान प्राप्त करें:

    #include <time.h>
    #include <sys/time.h>
    #include <stdint.h>
    
    uint64_t get_posix_clock_time ()
    {
        struct timespec ts;
    
        if (clock_gettime (CLOCK_MONOTONIC, &ts) == 0)
            return (uint64_t) (ts.tv_sec * 1000000 + ts.tv_nsec / 1000);
        else
            return 0;
    }

    मैं यहाँ microseconds के लिए समय कम कर दिया है।

  • पिछले समय के मूल्य के अंतर की गणना उसी तरह करें:

    uint64_t prev_time_value, time_value;
    uint64_t time_diff;
    
    /* Initial time */
    prev_time_value = get_posix_clock_time ();
    
    /* Do some work here */
    
    /* Final time */
    time_value = get_posix_clock_time ();
    
    /* Time difference */
    time_diff = time_value - prev_time_value;

gettimeofdayकॉल का उपयोग करने के लिए सबसे अच्छी गिरावट रणनीति है : यह एक मोनोटोनिक नहीं है, लेकिन यह काफी अच्छा प्रस्ताव प्रदान करता है। विचार के साथ ही है clock_gettime, लेकिन आपको एक समय मूल्य प्राप्त करना चाहिए:

#include <time.h>
#include <sys/time.h>
#include <stdint.h>

uint64_t get_gtod_clock_time ()
{
    struct timeval tv;

    if (gettimeofday (&tv, NULL) == 0)
        return (uint64_t) (tv.tv_sec * 1000000 + tv.tv_usec);
    else
        return 0;
}

फिर से, समय मान को माइक्रोसेकंड तक घटाया जाता है।

SGI IRIX

IRIX में clock_gettimeकॉल है, लेकिन इसका अभाव है CLOCK_MONOTONIC। इसके बजाय यह अपने आप ही monotonic घड़ी स्रोत के रूप में परिभाषित किया गया है CLOCK_SGI_CYCLEजो आप के बजाय का उपयोग करना चाहिए CLOCK_MONOTONICके साथ clock_gettime

सोलारिस और एचपी-यूएक्स

सोलारिस का अपना उच्च-रिज़ॉल्यूशन टाइमर इंटरफ़ेस है, gethrtimeजो नैनोसेकंड में वर्तमान टाइमर मान लौटाता है। हालांकि सोलारिस के नए संस्करण हो सकते हैं clock_gettime, आप gethrtimeपुराने सोलारिस संस्करणों का समर्थन करने की आवश्यकता होने पर चिपक सकते हैं ।

उपयोग सरल है:

#include <sys/time.h>

void time_measure_example ()
{
    hrtime_t prev_time_value, time_value;
    hrtime_t time_diff;

    /* Initial time */
    prev_time_value = gethrtime ();

    /* Do some work here */

    /* Final time */
    time_value = gethrtime ();

    /* Time difference */
    time_diff = time_value - prev_time_value;
}

एचपी-यूएक्स की कमी है clock_gettime, लेकिन यह समर्थन करता हैgethrtime जिसे आपको सोलारिस पर उसी तरह से उपयोग करना चाहिए।

BeOS

BeOS का अपना उच्च-रिज़ॉल्यूशन टाइमर इंटरफ़ेस भी है system_timeजो कंप्यूटर को बूट किए जाने के बाद माइक्रोसेकंड की संख्या को वापस ला देता है।

उदाहरण उपयोग:

#include <kernel/OS.h>

void time_measure_example ()
{
    bigtime_t prev_time_value, time_value;
    bigtime_t time_diff;

    /* Initial time */
    prev_time_value = system_time ();

    /* Do some work here */

    /* Final time */
    time_value = system_time ();

    /* Time difference */
    time_diff = time_value - prev_time_value;
}

ओएस / 2

OS / 2 के पास उच्च-परिशुद्धता समय टिकटों को प्राप्त करने के लिए अपना स्वयं का एपीआई है:

  • DosTmrQueryFreq(जीसीसी संकलक के लिए ) एक टाइमर आवृत्ति (प्रति यूनिट टिक्स) क्वेरी :

    #define INCL_DOSPROFILE
    #define INCL_DOSERRORS
    #include <os2.h>
    #include <stdint.h>
    
    ULONG freq;
    
    DosTmrQueryFreq (&freq);
  • क्वेरी के साथ वर्तमान टिक मूल्य DosTmrQueryTime:

    QWORD    tcounter;
    unit64_t time_low;
    unit64_t time_high;
    unit64_t timestamp;
    
    if (DosTmrQueryTime (&tcounter) == NO_ERROR) {
        time_low  = (unit64_t) tcounter.ulLo;
        time_high = (unit64_t) tcounter.ulHi;
    
        timestamp = (time_high << 32) | time_low;
    }
  • स्केल को बीता हुआ समय, अर्थात माइक्रोसेकंड तक:

    uint64_t usecs = (prev_timestamp - timestamp) / (freq / 1000000);

उदाहरण कार्यान्वयन

आप प्लासी लाइब्रेरी पर एक नज़र डाल सकते हैं जो उपरोक्त वर्णित सभी रणनीतियों को लागू करती है (विवरणों के लिए ptimeprofiler * .c देखें)।


"समय मापन समस्या के लिए पर्याप्त सटीकता के साथ कोई उचित एएनएसआई समाधान नहीं है": सी 11 है timespec_get: stackoverflow.com/a/36095407/895245
Ciro Santilli 郝海东 AN AN 六四 法轮功 法轮功

1
कोड निष्पादन के समय को मापने के लिए यह अभी भी एक गलत तरीका है। timespec_getमोनोटोनिक नहीं है।
अलेक्जेंडर सैप्रीकिन

11

timespec_get C11 से

कार्यान्वयन के संकल्प के लिए, नैनोसेकंड तक रिटर्न देता है।

POSIX से एक ANSI रिपॉफ की तरह दिखता है ' clock_gettime

उदाहरण: printfउबंटू 15.10 पर प्रत्येक 100ms किया जाता है:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

static long get_nanos(void) {
    struct timespec ts;
    timespec_get(&ts, TIME_UTC);
    return (long)ts.tv_sec * 1000000000L + ts.tv_nsec;
}

int main(void) {
    long nanos;
    long last_nanos;
    long start;
    nanos = get_nanos();
    last_nanos = nanos;
    start = nanos;
    while (1) {
        nanos = get_nanos();
        if (nanos - last_nanos > 100000000L) {
            printf("current nanos: %ld\n", nanos - start);
            last_nanos = nanos;
        }
    }
    return EXIT_SUCCESS;
}

C11 N1570 मानक प्रारूप 7.27.2.5 "timespec_get समारोह कहते हैं,":

यदि आधार TIME_UTC है, तो tv_sec सदस्य एक निर्धारित परिभाषित युग के बाद से सेकंड की संख्या पर सेट हो जाता है, पूरे मान पर काट दिया जाता है और tv_nsec सदस्य सिस्टम घड़ी के रिज़ॉल्यूशन के लिए नैनोसेकंड के अभिन्न नंबर पर सेट होता है। (321)

321) हालांकि एक संरचनात्मक टाइमस्पेक ऑब्जेक्ट नैनोसेकंड रिज़ॉल्यूशन के साथ समय का वर्णन करता है, उपलब्ध रिज़ॉल्यूशन सिस्टम निर्भर है और 1 सेकंड से अधिक भी हो सकता है।

C ++ 11 भी मिला std::chrono::high_resolution_clock: C ++ क्रॉस-प्लेटफ़ॉर्म हाई-रिज़ॉल्यूशन टाइमर

glibc 2.21 कार्यान्वयन

के sysdeps/posix/timespec_get.cरूप में पाया जा सकता है :

int
timespec_get (struct timespec *ts, int base)
{
  switch (base)
    {
    case TIME_UTC:
      if (__clock_gettime (CLOCK_REALTIME, ts) < 0)
        return 0;
      break;

    default:
      return 0;
    }

  return base;
}

इतना स्पष्ट रूप से:

  • केवल TIME_UTCवर्तमान में समर्थित है

  • यह आगे की ओर है __clock_gettime (CLOCK_REALTIME, ts), जो एक POSIX API है: http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html

    लिनक्स x86-64 में एक clock_gettimeसिस्टम कॉल है।

    ध्यान दें कि यह एक विफल-प्रूफ माइक्रो-बेंचमार्किंग विधि नहीं है क्योंकि:

    • man clock_gettimeयदि आपका प्रोग्राम चलते समय कुछ सिस्टम टाइम सेटिंग में बदलाव करता है, तो इस माप में असंतोष हो सकता है। यह पाठ्यक्रम की एक दुर्लभ घटना होनी चाहिए, और आप इसे अनदेखा करने में सक्षम हो सकते हैं।

    • यह दीवार के समय को मापता है, इसलिए यदि अनुसूचक आपके कार्य के बारे में भूलने का फैसला करता है, तो यह अधिक समय तक चलता रहेगा।

    उन कारणों से getrusage() यह एक बेहतर बेहतर POSIX बेंचमार्किंग टूल हो सकता है, इसके बावजूद कि यह माइक्रोसेकंड अधिकतम परिशुद्धता कम है।

    पर अधिक जानकारी: लिनक्स में समय को मापें - समय बनाम घड़ी बनाम गेट्रेज बनाम घड़ी_गेटाइम बनाम गेटटाइमऑफडे बनाम टाइमपेक_गेट?


यह 2017 का सही उत्तर है, यहां तक ​​कि MSVC का भी यह कार्य है; बेंचमार्किंग के संदर्भ में चिप रजिस्टर (पीटी एक्सटेंशन के साथ x86 प्रोसेसर के नए संस्करण और लिनक्स कर्नेल /

4

सबसे अच्छी परिशुद्धता जो आप संभवतः प्राप्त कर सकते हैं, x86- केवल "rdtsc" निर्देश के उपयोग के माध्यम से है, जो घड़ी-स्तरीय रिज़ॉल्यूशन प्रदान कर सकता है (निश्चित रूप से rdtsc कॉल की लागत को ध्यान में रखना चाहिए, जिसे आसानी से मापा जा सकता है अनुप्रयोग स्टार्टअप)।

यहां मुख्य पकड़ प्रति सेकंड घड़ियों की संख्या को माप रही है, जो बहुत कठिन नहीं होनी चाहिए।


3
आपको प्रोसेसर आत्मीयता के बारे में भी चिंतित होने की आवश्यकता हो सकती है, क्योंकि कुछ मशीनों पर आप एक से अधिक प्रोसेसर को आरडीटीसीटी कॉल भेज सकते हैं और उनके आरडीसीटी काउंटरों को सिंक्रनाइज़ नहीं किया जा सकता है।
विल डीन

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

Btw, @WillDean द्वारा उल्लिखित कोर बहाव और समय के लिए rdtsc का उपयोग करने का कारण यह है कि कई गेम काम करने में असफल रहे (शुरुआती?) मल्टी-कोर AMD64 CPUs - मुझे अपने X2 4400+ पर सिंगल-कोर एफिनिटी तक सीमित करना पड़ा था? कई उपाधियाँ।
स्नोमार्क

2

स्वीकृत उत्तर काफी अच्छा है। लेकिन मेरा समाधान अधिक सरल है। मैं अभी लिनक्स में परीक्षण करता हूं, gcc का उपयोग करता हूं (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0।

वरना उपयोग gettimeofday, tv_secदूसरे का हिस्सा है, और tv_usecहै माइक्रोसेकंड , नहीं मिली सेकंड

long currentTimeMillis() {
  struct timeval time;
  gettimeofday(&time, NULL);

  return time.tv_sec * 1000 + time.tv_usec / 1000;
}

int main() {
  printf("%ld\n", currentTimeMillis());
  // wait 1 second
  sleep(1);
  printf("%ld\n", currentTimeMillis());
  return 0;
 }

यह प्रिंट करें:

1522139691342 1522139692342, बिल्कुल दूसरा।


-4

खिड़कियों के नीचे:

SYSTEMTIME t;
GetLocalTime(&t);
swprintf_s(buff, L"[%02d:%02d:%02d:%d]\t", t.wHour, t.wMinute, t.wSecond, t.wMilliseconds);

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