1

I'm trying to have a loop execute for an exact time specified by executionTime. I am using ctime to get this timing, and I need it to be within a few milliseconds of accuracy (which I believe it is). Once that loop runs for the execution time specified, it should break.

My problem is for the execution time of 0.5, the result being printing is 1. Upon further testing it appears my program rounds up the execution time to the nearest integer. So for 4.5 executionTime, the execution time being printed is 5.0000000. My code is below. I am not sure where this error is coming from.

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

int main() 
{
    float  executionTime = 4.5; 
    int i;
    float  timeDifference = -1;  
    time_t t1;
    time_t t2;

    t1 = time(0);

    for (i = 0; i < 1000000000; i++) 
    {
        t2 = time(0); 

        timeDifference = difftime(t2, t1); 

        if (timeDifference >= executionTime) 
        { 
            break; 
        }

    }

    printf("time difference is: %f\n", timeDifference); 

    return 0; 

}

NEW VERSION trying to use clock_gettime. This version has the issue of never breaking when execution time is reached for some reason inside the loop.

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

#define BILLION 1E9 

int main()
{
    float  executionTime = 4.5;
    int i;
    float  elapsedTime = -1;

    struct timespec start;
    struct timespec stop;

    //Get starting time 
    clock_gettime(CLOCK_REALTIME, &start);

    for (i = 0; i < 1000000000; i++)
    {
        //Get current time
        clock_gettime(CLOCK_REALTIME, &stop);

        elapsedTime = ((stop.tv_sec - start.tv_sec) + (stop.tv_nsec - start.tv_nsec)) / BILLION;

        if (elapsedTime >= executionTime)
        {
            break;
        }
    }

    printf("time difference is: %f\n", elapsedTime);

    return 0;

}
Mr.Mips
  • 379
  • 2
  • 18
  • [The difftime() function returns the number of seconds elapsed between time time1 and time time0](http://man7.org/linux/man-pages/man3/difftime.3.html), thus `5 >= 4.5` breaks the loop. – kiran Biradar Feb 13 '19 at 19:53
  • It seems from [this question](https://stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to) that C does not guarantee a type for `time_t` so it could be that an integral type is passed to `difftime` resulting in a whole number of seconds for the time difference. – Weather Vane Feb 13 '19 at 19:56
  • strongly suggest (since `time()` has a granularity of 1 second) to use the function `setitimer()` Which is used to setup a interval and setting a signal when that interval has expired – user3629249 Feb 15 '19 at 01:42
  • @user3629249 Yes, I scrapped the `time()` usage and am now using the second portion newer version (further down on OG post). I'm using `clock_gettime()` now. – Mr.Mips Feb 15 '19 at 18:14

2 Answers2

1

time() returns to the nearest second and difftime() returns the difference of those. So basically this function compute difference of to integers. For a more accurate estimation you can use clock()

time_t purpose is for measuring calendar times

int main() 
{
    float  executionTime = 1.3; 
    int i;
    double  timeDifference = 1.0;  
    clock_t t1;
    clock_t t2;

    t1 = clock();

    for (i = 0; i < 1000000000; i++) 
    {
        timeDifference = (double)(clock() - t1) / CLOCKS_PER_SEC;

        if (timeDifference >= executionTime) 
        { 
            break; 
        }

    }

    printf("time difference is: %.9g\n", timeDifference); 

    return 0; 

}
bogdan tudose
  • 1,064
  • 1
  • 9
  • 21
  • I do not think I will be going with your example simply because Linux uses timespec in a lot of places, and it might beneficial to stick with that standard. However, your post is good for other situations :) – Mr.Mips Feb 13 '19 at 21:38
1

clock_gettime can be used to get greater accuracy.
Call delay with a value greater than 0 to set the delay time, then with -1 to check the elapsed time.
Calling clock_gettime in main will give the elapsed time in main.

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

#define BILLION  1E9

int delay ( double seconds)
{
    static double usec = 0.0;
    double elapsed = 0.0;
    static struct timespec start;
    struct timespec stop;

    if ( 0.0 <= seconds) {
        usec = seconds;
        clock_gettime ( CLOCK_REALTIME, &start);
        return 0;
    }
    clock_gettime ( CLOCK_REALTIME, &stop);
    elapsed = difftime ( stop.tv_sec, start.tv_sec);
    elapsed += ( stop.tv_nsec - start.tv_nsec) / BILLION;
    if ( ( elapsed < usec)) {
        return 1;
    }
    return 0;
}

int main() {

    double  executionTime = 4.5;
    int i;
    double  timeDifference = -1;
    struct timespec end;
    struct timespec begin;

    clock_gettime ( CLOCK_REALTIME, &begin);
    delay( executionTime);//call to set time

    for (i = 0; i < 1000000000; i++)
    {
        if ( !delay( -1)) {//call to check elapsed time
            break;
        }
    }
    clock_gettime ( CLOCK_REALTIME, &end);
    timeDifference = difftime ( end.tv_sec, begin.tv_sec);
    timeDifference += ( end.tv_nsec - begin.tv_nsec) / BILLION;

    printf("time difference is: %f\n", timeDifference);

    return 0;
}
xing
  • 2,125
  • 2
  • 14
  • 10
  • can you check out my edited version in OG post based on your example? The loop is not terminating after 4.5 seconds. I believe I'm comparing the times similar to the way you do it (just not as many moving pieces). – Mr.Mips Feb 13 '19 at 21:29