AverageTimer32 counter value becomes zero
Asked Answered
E

2

6

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

Eijkman answered 14/3, 2012 at 21:21 Comment(3)
Socrates: what's the average of no increments?Weeks
Sorry i did not get that question. Probably i am using the wrong counter ? I have updated the initial code with the requirement i have.Eijkman
It is the average duration during the time since the last measurement. If you're not logging anything it will become zero as the average duration is undefined (simplified to zero).Presidium
P
5

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.

Procreant answered 31/7, 2012 at 14:3 Comment(1)
I don't think this answer is correct. In the question, N is always incremented by the elapsed ticks. So it's not possible for N1 to be less than N0 (like in the first example). And thus the remaining conclusion is (probably) also incorrect.Psalm
S
0

I had similar problem. I had a good output in PerformanceMonitor by AverangeCounter. But in program an operation NextValue always returns 0. By the way in ElapsedTime counter the same operation return value that i want.

Then I understand core of AverageTimer32 (I hope). You shouldn't hope that AverageTimer32 will show averaged time of some work. It's just timer that average time for one operation and show it. If no work is going on than no time of operation exist and you will have 0 as value of counter.

if I take NextValue every time I add ticks to counter it return counts of seconds (as I understand it's return last value, not the average value. An AverageTimer32 counter has name that anyone can misunderstand). And if I cache it then I can convert it in more readable form and use it as value of counter in program (if you ask NextValue right after that in second time you receive 0).

Also I want to correct previous answer. You should use

10, 9, 8, 7 ,6

instead of

10, 19, 27, 34, 40

when you use method IncreaseBy and

10, 19, 27, 34, 40

when you set Stopwatch.GetTimestamp() manually in RawValue.

Sexed answered 7/7, 2013 at 11:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.