c प्रोग्राम प्रदर्शन को मापने के लिए लिनक्स में उच्च रिज़ॉल्यूशन टाइमर कैसे बनाएं?




linux timer (5)

clock_gettime , जो उच्च-रिज़ॉल्यूशन टाइमर के लिए एक POSIX इंटरफ़ेस है।

यदि, मैनपेज पढ़ने के बाद, आप CLOCK_REALTIME और CLOCK_MONOTONIC बीच के अंतर के बारे में सोच रहे हैं, CLOCK_REALTIME और CLOCK_MONOTONIC बीच अंतर देखें ?

एक पूर्ण उदाहरण के लिए निम्नलिखित पृष्ठ देखें: http://www.guyrutenberg.com/2007/09/22/profiling-code-using-clock_gettime/

#include <iostream>
#include <time.h>
using namespace std;

timespec diff(timespec start, timespec end);

int main()
{
    timespec time1, time2;
    int temp;
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
    for (int i = 0; i< 242000000; i++)
        temp+=temp;
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
    cout<<diff(time1,time2).tv_sec<<":"<<diff(time1,time2).tv_nsec<<endl;
    return 0;
}

timespec diff(timespec start, timespec end)
{
    timespec temp;
    if ((end.tv_nsec-start.tv_nsec)<0) {
        temp.tv_sec = end.tv_sec-start.tv_sec-1;
        temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
    } else {
        temp.tv_sec = end.tv_sec-start.tv_sec;
        temp.tv_nsec = end.tv_nsec-start.tv_nsec;
    }
    return temp;
}

मैं जीपीयू की तुलना सीपीयू प्रदर्शन से करने की कोशिश कर रहा हूं। एनवीआईडीआईए जीपीयू के लिए मैं बहुत सटीक समय प्राप्त करने के लिए cudaEvent_t प्रकारों का उपयोग कर रहा हूं।

सीपीयू के लिए मैं निम्नलिखित कोड का उपयोग कर रहा हूं:

// Timers
clock_t start, stop;
float elapsedTime = 0;

// Capture the start time

start = clock();

// Do something here
.......

// Capture the stop time
stop = clock();
// Retrieve time elapsed in milliseconds
elapsedTime = (float)(stop - start) / (float)CLOCKS_PER_SEC * 1000.0f;

जाहिर है, कोड का वह टुकड़ा केवल तभी अच्छा होता है जब आप सेकंड में गिन रहे हों। इसके अलावा, परिणाम कभी-कभी काफी अजीब आते हैं।

क्या किसी को लिनक्स में उच्च रिज़ॉल्यूशन टाइमर बनाने के किसी तरीके से पता है?


अब तक प्रस्तुत की गई जानकारी को सारांशित करने के लिए, ये सामान्य अनुप्रयोगों के लिए आवश्यक दो कार्य हैं।

#include <time.h>

// call this function to start a nanosecond-resolution timer
struct timespec timer_start(){
    struct timespec start_time;
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time);
    return start_time;
}

// call this function to end a timer, returning nanoseconds elapsed as a long
long timer_end(struct timespec start_time){
    struct timespec end_time;
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time);
    long diffInNanos = (end_time.tv_sec - start_time.tv_sec) * (long)1e9 + (end_time.tv_nsec - start_time.tv_nsec);
    return diffInNanos;
}

यहां इनपुट का एक सूची के भिन्नता की गणना करने में कितना समय लगता है, इस समय उनका उपयोग करने का एक उदाहरण यहां दिया गया है।

struct timespec vartime = timer_start();  // begin a timer called 'vartime'
double variance = var(input, MAXLEN);  // perform the task we want to time
long time_elapsed_nanos = timer_end(vartime);
printf("Variance = %f, Time taken (nanoseconds): %ld\n", variance, time_elapsed_nanos);

struct timespec t;
clock_gettime(CLOCK_REALTIME, &t);

CLOCK_REALTIME_HR भी है, लेकिन मुझे यकीन नहीं है कि इससे कोई फर्क पड़ता है ..


एपोल कार्यान्वयन: https://github.com/ielife/simple-timer-for-c-language

इस तरह प्रयोग करें:

timer_server_handle_t *timer_handle = timer_server_init(1024);
if (NULL == timer_handle) {
    fprintf(stderr, "timer_server_init failed\n");
    return -1;
}
ctimer timer1;
    timer1.count_ = 3;
    timer1.timer_internal_ = 0.5;
    timer1.timer_cb_ = timer_cb1;
    int *user_data1 = (int *)malloc(sizeof(int));
    *user_data1 = 100;
    timer1.user_data_ = user_data1;
    timer_server_addtimer(timer_handle, &timer1);

    ctimer timer2;
    timer2.count_ = -1;
    timer2.timer_internal_ = 0.5;
    timer2.timer_cb_ = timer_cb2;
    int *user_data2 = (int *)malloc(sizeof(int));
    *user_data2 = 10;
    timer2.user_data_ = user_data2;
    timer_server_addtimer(timer_handle, &timer2);

    sleep(10);

    timer_server_deltimer(timer_handle, timer1.fd);
    timer_server_deltimer(timer_handle, timer2.fd);
    timer_server_uninit(timer_handle);

क्या आप दीवार के समय में रुचि रखते हैं (वास्तव में कितना समय समाप्त हो जाता है) या चक्र गणना (कितने चक्र)? पहले मामले में, आपको gettimeofday जैसे कुछ का उपयोग करना चाहिए।

उच्चतम रिज़ॉल्यूशन टाइमर RDTSC x86 असेंबली निर्देश का उपयोग करता है। हालांकि, यह घड़ी की टिकटें मापता है, इसलिए आपको यह सुनिश्चित करना चाहिए कि पावर सेविंग मोड अक्षम है।

टीएससी के लिए विकी पेज कुछ उदाहरण देता है: http://en.wikipedia.org/wiki/Time_Stamp_Counter





high-resolution