Measuring time in C
Asked Answered
V

5

21

I'm trying to measure some activity in C (Matrix multiplying) and noticed that I should do something like this:

clock_t start = clock();
sleep(3);
clock_t end = clock();
double elapsed_time = (end - start)/(double)CLOCKS_PER_SEC;
printf("Elapsed time: %.2f.\n", elapsed_time);

The output is:

Elapsed time: 0.00.

Why is this happening?

Vic answered 31/10, 2012 at 10:39 Comment(4)
Did you try to print just (end - start)?Opinionated
Perhaps https://mcmap.net/q/659267/-timespec-equivalent-for-windows might help? Granularity, as Arno points, differs from machine to machine.Coachwork
[Rant] The most up-voted answer, with 11 upvotes, is irrelevant. But Arno's, or Orwell's (or my) answers (very similar) all have zero up-votes.Coachwork
I agree the OP confused clock vs. eg. time. But time will not help with his measuring 'matrix multiplication.'Coachwork
A
31

clock estimates the CPU time used by your program; that's the time the CPU has been busy executing instructions belonging to your program. sleep doesn't perform any work, so it takes no noticeable CPU time (even if it takes wallclock time).

If you want to measure wallclock time, use time:

time_t start = time(NULL);
sleep(3);
printf("%.2f\n", (double)(time(NULL) - start));

will print a number close to three.

Aristophanes answered 31/10, 2012 at 10:41 Comment(4)
MSDN time(): Return the time as seconds elapsed since midnight, January 1, 1970, or -1 in the case of an error. sleep(3) attempts to wait for 3 milliseconds. That little delay may not change the result of time() at all.Perreault
@Arno: on POSIX systems, sleep takes a number of second, not milliseconds.Aristophanes
Agree! This way you diagnoses this was Linux?Perreault
Why are we casting to a double? Isn't clock_t and time_t a long int?Lisabeth
B
14

As a side note, if you want to measure execution time in a more precise manner (milliseconds), time is not precise enough. You can use gettimeofday instead:

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>

int main() {
    long start, end;
    struct timeval timecheck;

    gettimeofday(&timecheck, NULL);
    start = (long)timecheck.tv_sec * 1000 + (long)timecheck.tv_usec / 1000;

    usleep(200000);  // 200ms

    gettimeofday(&timecheck, NULL);
    end = (long)timecheck.tv_sec * 1000 + (long)timecheck.tv_usec / 1000;

    printf("%ld milliseconds elapsed\n", (end - start));

    return 0;
}
Braille answered 19/8, 2017 at 9:5 Comment(0)
L
2

You must use time_t start = time(NULL); and time_t end = time(NULL); to get the correct values.

Limonite answered 31/10, 2012 at 10:43 Comment(0)
P
1

Use QueryPerformanceFrequency() as described in Orwells answer or use the GetSystemTimeAsFileTime() function. The latter has 100 ns granularity but does not increment at that rate. Its increment depends on underlaying hardware and the setting of multimedia timer resolution. Keep in mind that the frequency returned by QueryPerformanceFrequency() is treated as a constant. However, since it is generated by hardware it has an offset and a drift in time too. Measuring periods in time by using QueryPerformanceCounter() will typically be accompanied by errors of many microseconds per second. I've given this and this answer about similar matters.

Perreault answered 31/10, 2012 at 12:13 Comment(0)
E
0

If you don't care about being tied to Windows, you can try the high resolution timer. It's is a lot more precise than time(), which only has a precision of a single second because it the uses UNIX format.

#include <iostream>
#include <windows.h>

__int64 countspersec = 0;
double secpercount = 0.0;
__int64 starttime = 0;
__int64 curtime = 0;

int main() {

    // Get current time, and determine how fast the clock ticks
    QueryPerformanceCounter((LARGE_INTEGER*)&starttime);
    QueryPerformanceFrequency((LARGE_INTEGER*)&countspersec);
    secpercount = 1.0/(double)countspersec;

    /* calculate something */

    // Standard end-start stuff, account for clock speed
    QueryPerformanceCounter((LARGE_INTEGER*)&curtime);
    std::cout << "Time needed: " << (curtime-starttime)*secpercount << " sec\n";
    return 0;
}
Emersion answered 31/10, 2012 at 10:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.