I need to know how can I calculate the time of a function in C code in nanoseconds.
I tried to repeat the function until consume some microseconds. Are there any other functions in time.h that can be used to calculate the time in nanoseconds?
You are never going to get nanosecond accuracy. Think about what you are asking: on a 1 GHz CPU 1 nanosecond is a clock cycle. No matter what you attempt to call, you will never get that kind of accuracy, you are better off sticking to microseconds. A similar question with many examples is here: C++ Cross-Platform High-Resolution Timer.
For c only: on windows you want to use the QueryPerformanceCounter. And here is more on QPC. Here is a related question on how to use QueryPerformanceCounter.
Regardless of how you approach this or what type of system/OS you are using, you are getting an approximate answer at best, with considerable variance due to the nature of the problem.
Second, you need a system that supports this kind of call. It's pretty easy if you're using QNX Neutrino:
http://www.qnx.com/developers/docs/6.3.0SP3/neutrino/lib_ref/c/clock_gettime.html
/*
* This program calculates the time required to
* execute the program specified as its first argument.
* The time is printed in seconds, on standard out.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#define BILLION 1000000000L;
int main( int argc, char** argv )
{
struct timespec start, stop;
double accum;
if( clock_gettime( CLOCK_REALTIME, &start) == -1 ) {
perror( "clock gettime" );
return EXIT_FAILURE;
}
system( argv[1] );
if( clock_gettime( CLOCK_REALTIME, &stop) == -1 ) {
perror( "clock gettime" );
return EXIT_FAILURE;
}
accum = ( stop.tv_sec - start.tv_sec )
+ (double)( stop.tv_nsec - start.tv_nsec )
/ (double)BILLION;
printf( "%lf\n", accum );
return EXIT_SUCCESS;
}
The clock function in standard C is not useful for this. It usually has horrible resolution and it's inconsistent (between platforms) whether it measures elapsed wall time or cpu time consumed. You should use the POSIX-standard clock_gettime function (which has nanosecond resolution and lets you specify which clock you want to measure against) and emulate it with whatever system-specific clock operations are available on platforms that lack the POSIX function.
Call the function enough times that you get total time in the seconds, and use any method to measure (even plain C clock()). Measuring in micro/nanoseconds is inherently too imprecise.
For benchmarking, you want QueryPerformanceCounter. It is the best stopwatch available on Windows. See: How to use QueryPerformanceCounter? However using this to measure (for example) a single function call will still be inherently very imprecise; I think you need to time on the order of a second total to get good signal-to-noise ratio for your measurements. Take multiple measurements of whatever duration you want and compare their value to their standard deviation to make sure you are measuring sufficiently accurately.
Multimedia Timers are probably the best clock (note the difference between clock and stopwatch: one measures absolute time, the other time intervals only) available on Windows. You should be able to get near-millisecond resolution and precision with timeGetTime().
Related
I recently purchased a dev board for the max32660 MCU. I followed the instructions from the company's YouTube videos on how to set it up and got the example files working using the Eclipse IDE. I intend to use the time.h library to keep track of how long it takes to run various parts of my code, but whenever I try to printf() any clock_t type variables I just get back repeated 0.000000 values.
For the record: I am simply using my Arduino serial monitor to watch the signals come in from my USB port.
Maxim integrated youtube video:
https://www.youtube.com/watch?v=vpYBBYLkjTY&t=339s
Max32660 webpage
https://www.maximintegrated.com/en/products/microcontrollers/MAX32660.html
Code:
/***** Includes *****/
#include <stdio.h>
#include <stdint.h>
#include "mxc_device.h"
#include "led.h"
#include "board.h"
#include "mxc_delay.h"
#include "time.h"
/***** Definitions *****/
/***** Globals *****/
clock_t start;
clock_t end;
/***** Functions *****/
// *****************************************************************************
int main(void)
{
printf("Hello World!\n");
while (1) {
start = clock();
MXC_Delay(500000); //This part works fine
end = clock();
printf("%Lf\n", start); //I've tried many different versions of this
}
}
I've tried many different printf() configurations (%f, %lf, %ld, %s, %d, %i) and I cannot tell if the variables "start" and "end" are actually being saved as that value or if there is some problem with my serial port monitor reading the printf() statement, even though the "Hello World!" statement prints just fine.
I would expect to see any number besides 0.000000 being returned, particularly some integer that represents the number of clock cycles. I also expect that number to be somewhat low since the call to clock() is early in the script.
In most embedded standard libraries time() and clock() are not implemented or implemented as a "weak-link" stubs. You normally have to implement them yourself. In this case clock() and CLOCKS_PER_SEC are implementation dependent, you need to "re-targetting" the library to map this function to the hardware resources you choose to assign to that function. On a Cortex-M4 that would normally be a counter incremented in the SYSTICK interrupt at whatever rate (CLOCKS_PER_SEC) you choose for your platform.
You may already have support for SYSTICK and a system clock; in which case your clock() implementation might simply be a facade for that existing functionality.
Even if you had a working clock() the code:
printf("%Lf\n", start);
Is unlikely to produce a useful result in any case:
start is of type clock_t which is likely an alias for long, but certainly not long double.
Since any clock() implementation will be synchronous with whatever clock is used for MXC_Delay() the test simply measures itself!
end is unused so you are simply showin elapsed time, not the iteratuion time (that may be intended, in which case end is redundant). Perhaps you intended:
printf("%ld\n", (long)(end - start) ) ;
or possibly:
printf("%f\n", (double)(end - start) / CLOCKS_PER_SEC ) ;
I would doubt that on this target that long double is any larger than double in any event.
I'm struggling to make a timer in c that counts minutes and seconds. I'm trying to test it by printing the time to the console but it doesn't seem to show anything. Does anything look wrong in my code?
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define TRUE 1
int main( void )
{
int min = 0;
int sec = 0;
while (TRUE)
{
sec++;
Sleep(1000);
printf("%2d:%2d", min, sec);
if (sec == 59)
{
min++;
sec = 0;
}
}
return 0;
}
For performance reason, printf is buffered. That is, it won't display until the buffer is full. First thing to try is to add a new-line character to the end:
printf("%2d:%2d\n", min, sec);
If that doesn't work, you can force the output buffer to flush by calling fflush(stdout);
I would just check the system time rather than keeping track of seconds/minutes. This is because, your Sleep may not be exactly 1000ms, so over time your counter will not be accurate.
Since you're using Windows, here's a slightly modified version of your code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
int main()
{
for (;;)
{
time_t now = time(NULL);
struct tm* ptm = localtime(&now);
printf("%02d:%02d\n", ptm->tm_min, ptm->tm_sec);
Sleep(1000);
}
return 0;
}
I hope that helps.
As you ask, there are several things wrong in your code, I'll tell you as I read it. See below.
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define TRUE 1
int main( void )
{
int min = 0;
int sec = 0;
while (TRUE)
{
sec++;
Sleep(1000);
There's a problem with Sleep(). The thing is that you ask the kernel to pause your program for 1000 milliseconds, but that means that the kernel will awake your program 1 second after your call it to pause. This doesn't take into account the fact that the kernel will put in the schedule queue your process and it will, in general never take the cpu immediately, but after some delay. Then, even if you get the cpu immediately, your code will need some time to execute, making the total loop longer than 1000 ms. And your clock will be slow. It is better to get the system time and show it on the screen, or to take a timestamp when you start... and then show the difference in time from the start time to the timestamp you get at each display. The system time is maintained by an interrupt, that happens at regular intervals (by means of a precise clock oscillator) so you'll get a good clock time that way, instead of your slow clock (how slow it is will depend on things like how many other processes you are running on the system)
printf("%2d:%2d", min, sec);
This has already been stated in other answers, but let me explain how it works so you can understand how buffering works. A buffer is a large block of memory (normally it is 512 bytes) that is filled by printf() so it only calls write() when it has filled a complete buffer of data. This allows stdio to save system calls to do the actual writing and so, be more efficient when transferring large amounts of data.
On interactive applications, this is not applicable, as no output would be done if you don't force the buffers to fflush() before any input is done, so when the output is a tty device (something that stdio can know from the file descriptor associated to standard output) then it switches to line mode buffering, and that means that printf() will flush out the buffer when: 1) it is filled up, or 2) when a newline \n character is found in the output. So, one way to solve your problem is to put a \n at the end of the string, or to call fflush(stdout); after calling printf().
if (sec == 59)
as you increment your seconds before comparing, you have to check against 60 and not 59, as you compare with 60 to convert it to 0 after you have already incremented the seconds.
{
min++;
You should have to do the same with the minutes, when minutes get to 60. As you have not included this code, I assume you are not considering an hours chrono.
sec = 0;
}
}
return 0;
}
A complete solution for what I mean can be:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <windows.h>
int main()
{
long start_timestamp;
long display_timestamp;
start_timestamp = time(NULL);
for(;;) { /* this is the same as while(TRUE) */
display_timestamp = time(NULL);
int elapsed = display_timestamp - start_timestamp;
int min = elapsed / 60;
int sec = elapsed % 60;
/* the \r in next printf will make to print a single carry
* return in the same line, so the time updates on top of
* itself */
printf("\r%02d:%02d", min, sec); fflush(stdout);
Sleep(100); /* as you print the time elapsed, you don't
* mind if you shorten the time between
* displays. */
}
}
Does anything look wrong in my code?
Several things look wrong. The first is stdout line buffering - see eduffy's answer for that.
The second problem is that you're doing sec++; sleep(1000);, which means that sec will be incremented once every 1000 seconds or more.
The third problem is that if(sec == 59; is wrong and needs to be if(sec == 60). Otherwise you'll have 59 seconds per minute.
The fourth problem is that sleep(1) will sleep for at least 1 second, but may sleep for 2 seconds, or 10 seconds, or 1234 seconds. To guard against this you want something more like this:
expiry = now() + delay;
while(true) {
sleep(expiry - now() ):
expiry += delay;
}
The basic idea being that if one sleep takes too long then the next sleep will sleep less; and it'll end up being "correct on average".
The last problem is that sleep() doesn't really have enough precision. For 1 second delays you want to be able to sleep for fractions of a second (e.g. like maybe 9/10ths of a second). Depending on which compiler for which OS, there's probably something better you can use (e.g. maybe nanosleep()). Sadly there may be nothing that's actually good (e.g. some sort of "nanosleep_until(expiry_time)" that prevents jitter caused by IRQs and/or task switches that occur after you determine now but before you call something like "nanosleep()").
I am trying to read data from the ADC in the Beagle Bone, running Angstrom Linux distribution. I need to use a delay mechanism like sleep(), to only read samples at specific time, to help conform to a specific sample rate.
I also am required to calculate the execution time.
Here is a sample POC (proof of concept), to demonstrate the problem I am facing:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
clock_t begin, end;
while(1)
{
begin = clock();
sleep(1); // delay for 1 sec
end = clock();
printf("Execution time = %f\n",((float)(end-begin)/CLOCKS_PER_SEC));
}
}
I always get the execution time as 0.000000.
Why do I not get my result as 1.000000 seconds? My guess is calling sleep() will pre-empt my program, but I am not sure.
What other option do I have to calculate elapsed execution time which includes a delay?
Unix
The original versions of Unix didn't support sub-second timing, and only the latest versions of the C standard support sub-second 'real time' (aka 'wall time' or 'elapsed time'). At some point, ftime() was added, then gettimeofday(), then clock_gettime(), and the clock() function was standardized in C90.
The C standard, and Unix since at least 7th Edition UNIX™, has provided single-second accuracy with the time() function:
time_t now = time(0);
printf("%ld\n", (long)now);
7th Edition UNIX™ (or Version 7 UNIX™) provided millisecond resolution with ftime() — and it was included in POSIX up to and including the 2004 version (ftime()), but it is not part of POSIX 2008 or later, though it will still be supported on some machine types for reasons of backwards compatibility.
#include <sys/timeb.h>
struct timeb tb;
if (ftime(&tb) == 0)
printf("%ld.%.3d\n", (long)tb.time, tb.millitm);
POSIX also provided (and still provides) microsecond resolution timing via struct timeval and gettimeofday(). It is marked obsolescent in POSIX 2008. It may be the most portable timer.
#include <sys/time.h>
struct timeval tv;
if (gettimeofday(&tv, NULL) == 0)
printf("%ld.%.6d\n", (long)tv.tv_sec, tv.tv_usec);
Note that there are caveats about using gettimeofday() — its result can be affected if someone adjusts the system between successive calls. Similar comments apply to clock_gettime() and CLOCK_REALTIME.
POSIX is moving towards using nanosecond resolution timing, which is provided via struct timespec and clock_gettime(). With clock_gettime(), you must choose which clock you wish to measure. For many purposes, CLOCK_REALTIME is the correct choice (but CLOCK_MONOTONIC may be better for some purposes, if it is available).
#include <time.h>
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
printf("%ld.%.9d\n", (long)ts.tv_sec, ts.tv_nsec);
I'm not sure exactly where clock() came from. It wasn't in 7th Edition Unix, but it was in SVR4 with 100 for CLOCKS_PER_SEC. The C standard provides the clock() function (the POSIX specification for (clock() requires 1,000,000 for CLOCKS_PER_SEC; C does not). Note that this does not measure elapsed 'wall time'; it measures an approximation to the amount of CPU time that a process has used.
The clock() function shall return the implementation's best approximation to the processor time used by the process since the beginning of an implementation-defined era related only to the process invocation.
To determine the time in seconds, the value returned by clock() should be divided by the value of the macro CLOCKS_PER_SEC. [XSI] ⌦ CLOCKS_PER_SEC is defined to be one million in <time.h>. ⌫
clock_t clk = clock();
printf("%.6f\n", (double)clk / CLOCKS_PER_SEC);
Since the clock() function measures the CPU time used, not the wall clock time that elapses, it is wholly inappropriate to measure elapsed time when sleep() is used because a sleeping process uses no CPU time.
The C11 standard provides some thread-related functions which use struct timespec, which is defined to match the POSIX definition of the type. It also provides the function timespec_get():
7.27.2.5 The timespec_get function
#include <time.h>
int timespec_get(struct timespec *ts, int base);
¶2 The timespec_get function sets the interval pointed to by ts to hold the current calendar time based on the specified time base.
¶3 If base is TIME_UTC, the tv_sec member is set to the number of seconds since an implementation defined epoch, truncated to a whole value and the tv_nsec member is set to the integral number of nanoseconds, rounded to the resolution of the system clock.321)
¶4 If the timespec_get function is successful it returns the nonzero value base; otherwise, it returns zero.
321) Although a struct timespec object describes times with nanosecond resolution, the available resolution is system dependent and may even be greater than 1 second.
This function may not be widely available yet. It is not available on macOS 10.14.5 Mojave, for example, though it seems to be available in OpenBSD. It may be available in glibc (GNU C Library) but it isn't listed in the Linux man pages (neither in section 2 system calls or section 3 functions at https://linux.die.net, nor in section 2 system calls or section 3 functions at https://man7.org/). Equally clearly, it's trivial to implement a decent approximation to it if clock_gettime()is available:
#if !defined(HAVE_TIMESPEC_GET) && defined(HAVE_CLOCK_GETTIME)
enum { TIME_UTC = 1 };
static inline int timespec_get(struct timespec *ts, int base)
{
assert(base != 0);
if (clock_gettime(CLOCK_REALTIME, ts) != 0)
return 0;
return base;
}
#endif /* HAVE_TIMESPEC_GET */
Windows
Windows provides alternative interfaces, including GetTickCount() which returns a value in milliseconds since a reference time (valid up to 49 days) and QueryPerformanceCounter(). You may also find references to, and uses for, RDTSC — an Intel CPU instruction.
Printing time_t values
Note that throughout this code I've assumed that time_t values can be printed by converting the value to long and using the %ld format. That is correct for 64-bit Unix systems. It is correct for Windows 64-bit, and also for both Unix and Windows 32-bit systems until January 2038, when the value for the gap between the current time and 'The (Unix) Epoch' (1970-01-01 00:00:00 +00:00) grows bigger than 232 - 1 seconds — 32-bit arithmetic overflows. Then the cast type should be long long (which is guaranteed to be at least a 64-bit type) and the format should be %lld. The only issue (and reason for not doing it now) is the formats that MS Visual Studio supports — it uses non-standard names and format specifiers for 64-bit types, as I understand it.
Calculating elapsed time involves calculating differences between two values returned by these functions. Working with the structures is mildly fiddly; you have to deal with overflows or underflows when subtracting.
The solution to calculate execution time is to get the timestamp at the beginning of your program and at the end. Then make the difference.
#include <stdio.h>
#include <time.h>
int main() {
time_t begin;
time(&begin);
// Somethings
time_t end;
time(&end);
printf("Execution time %f\n", difftime(end, begin));
return (0);
}
EDIT:
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
int main() {
struct timeval tv;
gettimeofday(&tv, NULL);
double begin =
(tv.tv_sec) * 1000 + (tv.tv_usec) / 1000 ;
sleep(2);
gettimeofday(&tv, NULL);
double end =
(tv.tv_sec) * 1000 + (tv.tv_usec) / 1000 ;
printf("Execution time %f\n", end - begin);
return (0);
}
Indeed: during sleep(), the program doesn't run at all. And as clock() counts the CPU time and not the wall clock time, "no time passes".
Use time() instead.
clock_gettime is the function to use for this purpose. Do not use gettimeofday() ... It is deprecated and there is guidance AGAINST using it from the Opengroup and in Linux man pages.
<<
I use MACRO to print the elapse time.
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#define ELPS_TIME(func_name) do { \
struct timeval tval_before, tval_after, tval_result; \
gettimeofday(&tval_before, NULL); \
func_name; \
gettimeofday(&tval_after, NULL); \
timersub(&tval_after, &tval_before, &tval_result); \
printf("Time elapsed: %ld.%06ld seconds\n", \
(long int)tval_result.tv_sec, \
(long int)tval_result.tv_usec); } while(0)
static void test_func1() {
printf("%s:", __FUNCTION__);
sleep(1);
}
static void test_func2() {
printf("%s:", __FUNCTION__);
sleep(2);
}
int main() {
ELPS_TIME(test_func1()); //calling test_func1
ELPS_TIME(test_func2()); //calling test_func2
return 0;
}
Output:
test_func1:Time elapsed: 1.000103 seconds
test_func2:Time elapsed: 2.000974 seconds
Is there is a simple but sure way to measure the relative differences in performance between two algorithm implementations in C programs. More specifically, I want to compare the performance of implementation A vs. B? I'm thinking of a scheme like this:
In a unit test program:
start timer
call function
stop timer
get difference between start stop time
Run the scheme above for a pair of functions A and B, then get a percentage difference in execution time to determine which is faster.
Upon doing some research I came across this question about using a Monotonic clock on OSX in C, which apparently can give me at least nanosecond precision. To be clear, I understand that precise, controlled measurements are hard to perform, like what's discussed in "With O(N) known and system clock known, can we calculate the execution time of the code?, which I assume should be irrelevant in this case because I only want a relative measurement.
Everything considered, is this a sufficient and valid approach towards the kind of analysis I want to perform? Are there any details or considerations I might be missing?
The main modification I make to the timing scheme you outline is to ensure that the same timing code is used for both functions — assuming they do have an identical interface, by passing a function pointer to skeletal code.
As an example, I have some code that times some functions that validate whether a given number is prime. The control function is:
static void test_primality_tester(const char *tag, int seed, int (*prime)(unsigned), int count)
{
srand(seed);
Clock clk;
int nprimes = 0;
clk_init(&clk);
clk_start(&clk);
for (int i = 0; i < count; i++)
{
if (prime(rand()))
nprimes++;
}
clk_stop(&clk);
char buffer[32];
printf("%9s: %d primes found (out of %d) in %s s\n", tag, nprimes,
count, clk_elapsed_us(&clk, buffer, sizeof(buffer)));
}
I'm well aware of srand() — why call it once?, but the point of using srand() once each time this function is called is to ensure that the tests process the same sequence of random numbers. On macOS, RAND_MAX is 0x7FFFFFFF.
The type Clock contain analogues to two struct timespec structures, for the start and stop time. The clk_init() function initializes the structure; clk_start() records the start time in the structure; clk_stop() records the stop time in the structure; and clk_elapsed_us() calculates the elapsed time between the start and stop times in microseconds. The package is written to provide me with cross-platform portability (at the cost of some headaches in determining which is the best sub-second timing routine available at compile time).
You can find my code for timers on Github in the repository https://github.com/jleffler/soq, in the src/libsoq directory — files timer.h and timer.c. The code has not yet caught up with macOS Sierra having clock_gettime(), though it could be compiled to use it with -DHAVE_CLOCK_GETTIME as a command-line compiler option.
This code was called from a function one_test():
static void one_test(int seed)
{
printf("Seed; %d\n", seed);
enum { COUNT = 10000000 };
test_primality_tester("IsPrime1", seed, IsPrime1, COUNT);
test_primality_tester("IsPrime2", seed, IsPrime2, COUNT);
test_primality_tester("IsPrime3", seed, IsPrime3, COUNT);
test_primality_tester("isprime1", seed, isprime1, COUNT);
test_primality_tester("isprime2", seed, isprime2, COUNT);
test_primality_tester("isprime3", seed, isprime3, COUNT);
}
And the main program can take one or a series of seeds, or uses the current time as a seed:
int main(int argc, char **argv)
{
if (argc > 1)
{
for (int i = 1; i < argc; i++)
one_test(atoi(argv[i]));
}
else
one_test(time(0));
return(0);
}
I'm trying to optimize a chunk of code given to me by a friend but my baseline for average execution times of it are extremely erratic and I'm lost to as why/how to fix it.
Code:
#include <sys/time.h>
#include <time.h>
#include <stdio.h>
#include "wall.h" /* Where his code is */
int main()
{
int average;
struct timeval tv;
int i;
for(i = 0; i < 1000; i++) /* Running his code 1,000 times */
{
gettimeofday(&tv, NULL); /* Starting time */
start(); /* Launching his code */
int ret = tv.tv_usec; /* Finishing time */
ret /= 1000; /* Converting to milliseconds */
average += ret; /* Adding to the average */
}
printf("Average execution time: %d milliseconds\n", average/1000);
return 0;
}
Output of 5 different runs:
804 milliseconds
702 milliseconds
394 milliseconds
642 milliseconds
705 milliseconds
I've tried multiple different ways of getting the average execution time, but each one either doesn't give me a precise enough answer or gives me a completely erratic one. I'm lost as to what to do now, any help would be greatly appreciated!
I know these types of benchmarks are very much system dependent, so I've listed my system specs below:
Ubuntu 12.10 x64
7.8 GiB RAM
Intel Core i7-3770 CPU # 3.40GHz x 8
GeForce GT 620/PCIe/SSE2
Edit
Thank you all for your input but I decided to go with a gprof instead of constructing my own. Thank you, once again!
Your line int ret = tv.tv_usec; /* Finishing time */ doesn't give you the finishing time, it's still the starting time. You should make a second struct timeval, call gettimeofday with that and compare the two.
However, using clock() is probably easier. Of course, if you want to really analyse the performance of your code use a profiler.
There are several problems here, including zero details on what the code you're benchmarking is doing, and that you're using "gettimeofday()" incorrectly (and, perhaps, inappropriately).
SUGGESTIONS:
1) Don't use "gettimeofday()":
http://blog.habets.pp.se/2010/09/gettimeofday-should-never-be-used-to-measure-time
2) Supplement your "time elapsed" with gprof:
http://www.cs.duke.edu/~ola/courses/programming/gprof.html