-3

In the following code, how to measure total elapsed time of function1() and function3()?

In the real situation, function1() and function3() are scattered everywhere in a complex program. I need something that can use the name of the function to start and stop a timer so in the end I can print out how long each function takes in total.

Please note that the time elasped of function1() is not the needed value. The total time elasped of function1() which is called everywhere many times is the needed value.

int function1()
{
    int i = 1;
    i++;
    return i;
}
int function2()
{
    int i = 1;
    i++;
    return i;
}
int function3()
{
    int i = 1;
    i++;
    return i;
}
int main(int argc, char *argv[])
{
    size_t t = 0;

    while (t < 1000000)
    {
        // I want something like startTimer(function1)
        function1();
        // I want something like pauseTimer(function1)
        function2();
        // I want something like startTimer(function3)
        function3();
         // I want something like pauseTimer(function3)
    }
    // printTimer() here will print the total elapsed time of function 1 and 
    //function 3
    getchar();
    return 0;
}
Ronald Ku
  • 319
  • 2
  • 14
  • 2
    Besides that your example doesn't even compile, did you try anything already? I don't get what's actually the problem. You may use the functions from `std::chrono` to achieve that. – user0042 Aug 15 '17 at 02:23
  • I am sorry. The code is not what i am writing but a reflection of the real situation i m facing. I have edited it to make it compile. I have used std::map for the timer management but the overhead is too huge. I did use std::chrono in the core part. It is easy to measure the time elasped of a single function when it happens once. It is hard when the function is scattered everywhere and I have to measure the total time – Ronald Ku Aug 15 '17 at 02:59
  • 4
    You probably want a profiling tool. – user0042 Aug 15 '17 at 03:03
  • What operating system(s) are you using to develop on? @user0042's suggestion of using a profiling tool is spot on. – Brian Cain Aug 15 '17 at 03:06
  • I am using windows visual studio. I hear that visual studio seems to have a time profiling tool. I prefer portable light weight code more so I do not need to be platform dependent. – Ronald Ku Aug 15 '17 at 03:09
  • @user0042 What time profile tool are you suggesting to do the job, i.e. measure the total time elapsed of a particular function? I have looked into Very Sleepy and CodeXL but they seem to be too huge for my application. – Ronald Ku Aug 15 '17 at 03:27
  • @RonaldKu Depends on your toolchain. gprof works well for gcc. – user0042 Aug 15 '17 at 03:29
  • Take a look at [std chrono](http://en.cppreference.com/w/cpp/chrono). – frogatto Aug 15 '17 at 04:04
  • Possible duplicate of [Easily measure elapsed time](https://stackoverflow.com/questions/2808398/easily-measure-elapsed-time) – Lior Kogan Aug 15 '17 at 04:17

2 Answers2

1

Running a profiler is probably the best way to do it, but if you can't do that for some reason, you could do the following:

1) Temporarily rename function1()'s implementation to e.g. function1_implementation() (or similar)

2) Write a new temporary implementation of function1() like this:

 static unsigned long long totalMicrosInFunction1 = 0;

 // Returns current system-clock-time, in microseconds
 static unsigned long long get_current_time_in_microseconds()
 {
    // This may not be the best way to implement this function; see below
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return ((unsigned long long)tv.tv_sec)*1000000 + tv.tv_usec;
 }

 int function1()
 {
    unsigned long long startTime = get_current_time_in_microseconds();
    int ret = function1_implementation();  // call the real code!
    unsigned long long endTime = get_current_time_in_microseconds();

    totalMicrosInFunction1 += (endTime-startTime);
    return ret;
 }

3) Do the same sort of trick for any other functions you want to time.

... then recompile your program, and at the end of main(), print out the current value of totalMicrosInFunction1.

Note that the above implementation of get_current_system_time_in_microseconds() may not be the best one for your use-case; if you're using C++11, you can use std::chrono::high_resolution_clock for this purpose instead; otherwise you could use an OS-specific API like QueryPerformanceCounter() under windows.

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
  • If I am using a time profiling tools, when my program has over 1000 functions and there are only 10 functions I am interested, do I have the option to only view that 10 functions? – Ronald Ku Aug 15 '17 at 03:59
  • Presumably; it would of course depend on the tool you are using. – Jeremy Friesner Aug 15 '17 at 04:23
1

Assuming you are running on a PC with a single CPU module, you can use the rdtscp instruction and get the number of ticks. Accumulate the ticks. When done, convert ticks to time, and you are done.

Look at link: https://msdn.microsoft.com/en-us/library/bb385235.aspx for how to do rdtscp on Windows.

This is written assuming you only have a single thread.

Now, create a variable "unsigned __int64 totalTicks = 0;" at file scope.

Function1 would be written as follows:

int function1()
{
    unsigned int arg;
    unsigned __int64 startTicks = __rdtscp(&arg); // arg is not used
    int ret = function1_implementation();  // call the real code!
    unsigned __int64 endTicks = __rdtscp(&arg);
    totalTicks += (endTicks - startTicks);

    return ret;
}

A tick is the inverse of the CPU clock rate, so a 2.5GHz CPU will have 2.5 billion ticks in a second.

Alternately, you can create a Timer class that does the core functionality I describe - create start() and stop() methods to return the two values, and an elapsed() method to return the delta. Call start() at the beginning of any function, and the elapsed() at the end. Then, any function that needs a unique timer can use a different instance of Timer.

This will give sub-nanosecond resolution on modern CPUs. Using the monotonic time answers might not give you enough resolution if your function is small and fast. This is also the problem using profilers, as they usually statistically sample, at a clock rate of 10ms (gprof on Linux), so you will get accurate counts, but only estimates of the time spent.

digger
  • 74
  • 5