Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AverageTimer32 counter value becomes zero

I have written a piece of code like this below:

For testing i call the method ComputeAndLog and in the performance monitor i can see the non-zero average value. However as soon as i end my testing, the average performance counter value drops to zero. Any idea why thats the case ?

Probably i am using the wrong counters ?

The requirement I have is that I have a function and i have to calculate that on average, how much time that function takes to complete. Something like below:

void ComputeAndLog()
{
    Stopwatch stopWatch = Stopwatch.StartNew();
    FunctionWhoseAveragetTimeIsToBeMeasured();
    write_counter(stopWatch.ElapsedTicks);
}

void write_counter(long timeForCompletion)
{
    averageTimeCounter.IncrementBy(timeForCompletion);
    averageBaseCounter.Increment();
}

Thanks xoxo

like image 931
Thakur Sahib Avatar asked Mar 14 '12 21:03

Thakur Sahib


1 Answers

The AverageTimer32/64 does not calculate the average of all measurements you perform. Instead it provides the ration of your measurements to the number of operations you measured.

Basically, the issue with your code is the fact you are using a new timer every time you perform a measurement.

To understand how the AverageTimer works, it might be helpful to understand the formula behind it. This also answers why one needs an AverageBase to use an AverageTimer.

The formula for the AverageTimer is as following:

((N1 - N0) / F) / (B1 - B0)

with

  • N1 current reading at time t (AverageTimer)
  • N0 reading before, at t - 1 (AverageTimer)
  • B1 current counter at t (AverageBase)
  • B0 counter before, at t - 1 (Average Base)
  • F Factor to calculate ticks/seconds

In a nutshell the formular takes the current time in ticks and subtracts the previous one. The result divided by the factor F gives you the time you operation run since the last measurement taken at t-1.

Now you divide this by the current counter minus the counter before. This might be usually one. As a result you have the average time of your operation for one measurement.

Using the AverageBase you now can step over various measurement points. Think of a case where you can set the counter only every tenth operation you perform. Since your last measurement you would increment the AverageTimer by the new time measurement for all ten operations but increment the AverageBase by ten. Eventually, you will receive the average time for one operation (even if you have measured over all ten operation calls).

Looking at your code example you send in always the difference from timer start to timer end. Let this be a series of numbers like 10, 9, 8, 7 ,6 while increasing the AverageBase by 1.

For the second measurement you know will receive the following result:

(9 - 10) / F / (1 - 0) = -1 / F / 1

With F being 1 for simplicity you will get -1 as result.

The correct values to submit however should be

10, 19, 27, 34, 40

Again the same example we will get

(19 - 10) / F / (1 - 0) = 9 / F / 1

Again, with F being 1 you will have an average time of 9 for your operation. As you can see, the next value measured needs to be greater than the previous one so the AverageTimer works properly.

In your example you might use a global Stopwatch. Instead of starting it new, use Start() (not Restart()). As seen above, the counter will calculate the difference in time internally. That way you will get correct measurements.

Going to zero also makes sense, once you are done with your testing or your program ends, the counter will probably be closed and not provide any values anymore. You can do it manually by calling the Close() method on the counter.

like image 179
aheil Avatar answered Oct 10 '22 17:10

aheil