I have to change the get_seconds() with my current method called get_current_time_seconds3() and by then check the observation in difference between ways of measuring time. And by that see which of these two functions seems best suited for casche peformance analysis.
I'm not quite sure how to handle this problem. Can anyone please guide me?
#include <stdio.h>
#include <time.h>
#include <stdint.h>
#define BILLION 1000000000L
#define LIMIT_I 1000
#define LIMIT_J 1000
double get_current_time_seconds1()
{
/* Get current time using gettimeofday */
time_t t = time(NULL);
struct tm *tm = localtime(&t);
printf("%s\n", asctime(tm));
return (double) tm;
}
double get_current_time_seconds2()
{
struct timespec start,stop;
clock_gettime(CLOCK_REALTIME, &start);
clock_gettime(CLOCK_REALTIME, &stop);
double x = (stop.tv_sec - start.tv_sec) + (stop.tv_nsec - start.tv_nsec);
printf("%lf\n", x);
return (double) x;
}
double get_current_time_seconds3()
{
/*struct sysinfo info;
sysinfo(&info);
const time_t boottime = time(NULL) - info.uptime;
struct timespec monotime;
clock_gettime(CLOCK_MONOTONIC, &monotime);
time_t curtime = boottime + monotime.tv_sec;
printf("Current time = %s", ctime(&curtime));*/
uint64_t diff;
struct timespec start, end;
clock_gettime(CLOCK_MONOTONIC, &start);
sleep(5);
clock_gettime(CLOCK_MONOTONIC, &end);
diff = BILLION * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec;
printf("elapsed time = %llu nanoseconds\n", (long long unsigned int)diff);
return (double) diff;
}
static void printres(clockid_t id)
{
struct timespec ts;
int rc = clock_getres(id, &ts);
printf("clock id: %d\n", (unsigned int)id);
if (rc != 0)
{
printf("Error: %d\n", rc);
return;
}
printf("tv_sec = %lu\ntv_nsec = %lu\n", ts.tv_sec, ts.tv_nsec);
}
int main(int argc, char **argv)
{
printres(CLOCK_REALTIME);
printres(CLOCK_MONOTONIC);
printres(CLOCK_PROCESS_CPUTIME_ID);
printres(CLOCK_THREAD_CPUTIME_ID);
return 0;
}
Related
Consider the following code:
struct timespec ts;
uint64_t start_time;
uint64_t stop_time;
if (clock_gettime(CLOCK_REALTIME, &ts) != 0) {
abort();
}
start_time = ts.tv_sec * UINT64_C(1000000000) + ts.tv_nsec;
/* some computation... */
if (clock_gettime(CLOCK_REALTIME, &ts) != 0) {
abort();
}
stop_time = ts.tv_sec * UINT64_C(1000000000) + ts.tv_nsec;
printf("%" PRIu64 "\n", (stop_time - start_time + 500000000) / 1000000000);
In the vast majority of cases, the code works as I expected, i.e., prints the number of seconds that took the computation.
Very rarely, however, one anomaly occurs.
The program reports the number of seconds like 18446743875, 18446743877, 18446743962, etc.
I figured this number roughly matched 264 nanoseconds (~584 years).
So I got the suspicion that ts.tv_nsec is sometimes equal to −1.
So my question is:
What's wrong with my code?
Where and why does adding 264 nanoseconds happen?
I don't see anything wrong with your code. I suspect your OS is occasionally delivering an anomalous value for CLOCK_REALTIME — although I'm surprised, and I can't quite imagine what it might be.
I suggest rewriting your code like this:
struct timespec start_ts, stop_ts;
uint64_t start_time;
uint64_t stop_time;
if (clock_gettime(CLOCK_REALTIME, &start_ts) != 0) {
abort();
}
start_time = start_ts.tv_sec * UINT64_C(1000000000) + start_ts.tv_nsec;
/* some computation... */
if (clock_gettime(CLOCK_REALTIME, &stop_ts) != 0) {
abort();
}
stop_time = stop_ts.tv_sec * UINT64_C(1000000000) + stop_ts.tv_nsec;
uint64_t elapsed = (stop_time - start_time + 500000000) / 1000000000;
printf("%" PRIu64 "\n", elapsed);
if(elapsed > 365 * 86400 * UINT64_C(1000000000)) {
printf("ANOMALY:\n");
printf("start_ts = %lu %lu\n", start_ts.tv_sec, start_ts.tv_nsec);
printf("stop_ts = %lu %lu\n", stop_ts.tv_sec, stop_ts.tv_nsec);
}
Then, if/when it happens again, you'll have more information to go on.
I'm working with real time operating system Ecos.
i run this code on ubuntu :
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
static int tv_diff(struct timeval *t1, struct timeval *t2)
{
return
(t1->tv_sec - t2->tv_sec) * 1000 +
(t1->tv_usec - t2->tv_usec) / 1000;
}
int main(void)
{
struct timespec ts;
struct timeval tv1, tv2;
printf("Hello, eCos !\n");
clock_gettime(1, &ts);
tv1.tv_sec = ts.tv_sec;
tv1.tv_usec = ts.tv_nsec / 1000;
printf("Time: %ld \n", tv1.tv_sec);
sleep(10);
clock_gettime(1, &ts);
tv2.tv_sec = ts.tv_sec;
tv2.tv_usec = ts.tv_nsec / 1000;
printf("Time: %ld \n", tv2.tv_sec);
printf("diff Time: %d \n", tv_diff(&tv2, &tv1));
return 0;
}
and it worked properly :
root#ubuntu:/home/feres/Bureau# ./amin
Hello, eCos !
Time: 45417
Time: 45427
diff Time: 10000
but when i run it on ecos ( wich it work on qemu ) it give me this results
Hello, eCos !
Time: 0
Time: 0
diff Time: 0
is there any missing package on ecos (or qemu) or is there any specific commande to get time on ecos (or qemu)
Looks like your ECOS-HAL is not correctly set up (so that the system tick gets updated on a regular basis).
Im trying to write to the terminal one line at a time but it just prints the whole thing without sleeping. It works if I use sleep(1). Am I just not understanding how nanosleep is suppose to work?
void
display_all(int fdin, int fdout)
{
struct timespec tm1,tm2;
tm1.tv_sec = 0;
tm1.tv_nsec = 1000000000L;
while (display_line(fdin, fdout) == 80)
{
nanosleep(&tm1,&tm2);
}
}
display_line is using the function write to write to STDOUT.
From the nanosleep man page:
The value of the nanoseconds field must be in the range 0 to 999999999
#include <stdio.h>
#include <time.h>
#define MILISECONDS 300
#define NLOOPS 10
void nsleep(long miliseconds) {
struct timespec ts = {0, miliseconds * 1000000L};
nanosleep(&ts, NULL);
}
int main() {
short i;
for (i = 0; i < NLOOPS; i++)
fflush(stdout),
nsleep((long) MILISECONDS),
printf("%d miliseconds\n", MILISECONDS);
return 0;
}
Or:
void nsleep(long miliseconds) {
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = miliseconds * 1000000L;
nanosleep(&ts, NULL);
}
I'm trying to record the time my program takes to finish in seconds, with sub-second accuracy.
I'm not recording CPU time or cycles, I simply want to be able to mark a start point (Wall Clock time), then at the end of my program mark a finish (Wall Clock time), and calculate the delta.
Have a look at the function:
int clock_gettime(clockid_t clk_id, struct timespec *tp);
The function will fill the structure struct timespec you provide. Here is its definition:
struct timespec {
time_t tv_sec; /* secondes */
long tv_nsec; /* nanosecondes */
};
So the returned time in nanosecondes is: tp->tv_sec * 1e9 + tp->tv_nsec.
You can find all the possible clk_id in the man. I would recommend you to use CLOCK_MONOTONIC as it guarantees you that the time given will always be continuous, even if the time of the system is modified.
Just call time(NULL) to get the current time and use difftime to calculate the time between two points.
#include <time.h>
// ...
time_t start = time(NULL);
// do stuff here
time_t end = time(NULL);
printf("Took %f seconds\n", difftime(end, start));
This displays start/end time stamps and calculates a delta in seconds.
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
void print_timestamp(char *, time_t);
int main (int argc, char *argv[]) {
time_t start = time(0);
print_timestamp("Start: ", start);
sleep(2);
time_t end = time(0);
print_timestamp("End: ", end);
double diff = difftime(end, start);
printf("Elapsed: %5.2lf seconds\n", diff);
}
void
print_timestamp(char *msg, time_t time) {
struct tm *tm;
if ((tm = localtime (&time)) == NULL) {
printf ("Error extracting time stuff\n");
return;
}
printf ("%s %04d-%02d-%02d %02d:%02d:%02d\n",
msg,
1900 + tm->tm_year,
tm->tm_mon+1,
tm->tm_mday,
tm->tm_hour,
tm->tm_min,
tm->tm_sec);
}
Sample output:
Start: 2017-02-04 15:33:36
End: 2017-02-04 15:33:38
Elapsed: 2.00 seconds
You may also be able to use the time command available on (at least) Unix systems.
After compiling your program, run the command like this:
# compile your code
$ gcc foo.c -o foo
# compute the time
$ time ./foo
You can use the clock() function to record the number of ticks taken and then convert this to seconds:
#include <time.h>
#include <stdio.h>
#include <math.h>
int main () {
clock_t start_t = clock();
double a=0;
for(int i=0; i< 10000000; i++) {
a+=sqrt(a);
}
clock_t end_t = clock();
double total_t = (double)(end_t - start_t) / CLOCKS_PER_SEC;
printf("Total time taken by CPU: %lf\n", total_t );
return(0);
}
#include <features.h>
#include <time.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef unsigned int uint32;
#define million 1000000L
long duration2ms, duration10ms, duration100ms;
double Task2ms_Raster, Task10ms_Raster, Task100ms_Raster;
timer_t firstTimerID, secondTimerID, thirdTimerID;
void TASK1(Task2ms_Raster) {
struct timespec start, stop;
int a, b, c;
uint32 StartTime, StopTime;
a=1, b=2, c=3;
if((StartTime = clock_gettime(CLOCK_REALTIME, &start)) == -1) {
perror("clock gettime");
}
a= b+c;
b = c+a;
c= a+b;
b = c+a;
c= a+b; a= b+c;
b = c+a;
c= a+b; a= b+c;
b = c+a;
c= a+b; a= b+c;
b = c+a;
c= a+b; a= b+c;
b = c+a;
c= a+b; a= b+c;
b = c+a;
c= a+b; a= b+c;
b = c+a;
c= a+b;
// I did several times like this.
printf("ETAS\n");
printf("ETAS1\n");
if((StopTime = clock_gettime( CLOCK_REALTIME, &stop)) == -1) {
perror("clock gettime");
}
duration2ms = (stop.tv_sec - start.tv_sec) +
(double)(stop.tv_nsec - start.tv_nsec) /
(double)million;
printf("time difference is= %ld\n", duration2ms);
}
void TASK2(Task10ms_Raster) {
struct timespec start, stop;
if(clock_gettime( CLOCK_REALTIME, &start) == -1) {
perror("clock gettime");
}
printf("ETAS2\n");
printf("ETAS3\n");
if(clock_gettime(CLOCK_REALTIME, &stop) == -1) {
perror("clock gettime");
}
duration10ms = (stop.tv_sec - start.tv_sec) +
(double)( stop.tv_nsec - start.tv_nsec) /
(double)million;
printf("time difference is= %ld\n", duration10ms);
}
void TASK3(Task100ms_Raster) {
struct timespec start, stop;
if(clock_gettime( CLOCK_REALTIME, &start) == -1) {
perror("clock gettime");
}
printf("ETAS4\n");
printf("ETAS5\n");
if((clock_gettime(CLOCK_REALTIME, &stop)) == -1) {
perror("clock gettime");
}
duration100ms = (stop.tv_sec - start.tv_sec) +
(double)(stop.tv_nsec - start.tv_nsec) /
(double)million;
printf( "time difference is= %ld\n", duration100ms );
}
static void timerHandler(int sig, siginfo_t *si, void *uc) {
timer_t *tidp;
tidp = si->si_value.sival_ptr;
if (*tidp == firstTimerID)
TASK1(Task2ms_Raster);
else if(*tidp == secondTimerID)
TASK2(Task10ms_Raster);
else if(*tidp == thirdTimerID)
TASK3(Task100ms_Raster);
}
static int makeTimer(char *name,
timer_t *timerID,
int expireMS,
int intervalMS) {
struct sigevent te;
struct itimerspec its;
struct sigaction sa;
int sigNo = SIGRTMIN;
/* Set up signal handler. */
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = timerHandler;
sigemptyset(&sa.sa_mask);
if(sigaction(sigNo, &sa, NULL) == -1) {
perror("sigaction");
}
/* Set and enable alarm */
te.sigev_notify = SIGEV_SIGNAL;
te.sigev_signo = sigNo;
te.sigev_value.sival_ptr = timerID;
timer_create(CLOCK_REALTIME, &te, timerID);
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = intervalMS * 1000000;
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = expireMS * 1000000;
timer_settime(*timerID, 0, &its, NULL);
return 1;
}
int main(void) {
makeTimer("First Timer", &firstTimerID, 2, 2); //2ms
makeTimer("Second Timer", &secondTimerID, 10, 10); //10ms
makeTimer("Third Timer", &thirdTimerID, 100, 100); //100ms
while(1) {
sleep(100);
}
}
I created a timer to call the task for every 2ms, 10ms and 100ms. The tasks are just printing the value and calculating the start time and stop time for printing the value. when i run the above program, it is not displaying time difference between the start time and stop time (i.e duration2ms, duration 10ms nd duration100ms). could someone please help me.
The problem is that you don't save your timing values in TASK*() anywhere. This means clock_gettime() gets called twice in a row, having little or no time spent in between. What you should do is something along the lines of following:
#include <features.h>
#include <time.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef unsigned int uint32;
timer_t tmr;
struct timespec prev;
static void handle_timer(int sig, siginfo_t *si, void *uc) {
timer_t *tidp;
struct timespec current;
tidp = si->si_value.sival_ptr;
clock_gettime(CLOCK_REALTIME, ¤t);
printf("dif between calls to handle_timer: %ld\n",
current.tv_sec - prev.tv_sec);
prev = current;
}
int main(int argc, char **argv) {
struct sigevent se;
struct itimerspec its;
struct sigaction sa;
clock_gettime(CLOCK_REALTIME, &prev);
/* Set up signal handler. */
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handle_timer;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGRTMIN, &sa, NULL) == -1)
perror("sigaction");
/* Set and enable alarm */
se.sigev_notify = SIGEV_SIGNAL;
se.sigev_signo = SIGRTMIN;
se.sigev_value.sival_ptr = &tmr;
timer_create(CLOCK_REALTIME, &se, &tmr);
its.it_interval.tv_sec = 1;
its.it_value.tv_sec = 1;
its.it_value.tv_nsec = 0;
timer_settime(&tmr, 0, &its, NULL);
while(1)
sleep(100);
return 0;
}
The difference here is that we're actually saving the time when handle_time() was called and then calculating the difference against the saved time.
The time difference is going to show zero in all cases because you are measuring the time it takes to print two lines, which is very fast. You are not timing the time between invocations of each task.
If you want to measure the time between invocations of the task, you need to preserve the time. As an example, I'll show one task:
void TASK3(Task100ms_Raster) {
static struct timespec start, stop = { .tv_sec = -1 }; // static duration!
if (stop.tv_sec < 0) {
(void) clock_gettime( CLOCK_REALTIME, &stop); // first time run
}
start = stop; // start from previous stop time
// do whatever here
(void) clock_gettime( CLOCK_REALTIME, &stop);
duration100ms = (stop.tv_sec - start.tv_sec)
+ (double)(stop.tv_nsec - start.tv_nsec)
/ (double)million;
printf( "time difference is= %ld\n", duration100ms );
}