-1

In C# I am using the Stopwatch class. I can get the ticks, and milliseconds with no problems.

Now that I am testing code while learning C++ I try to get measurements but I don't know where the results are that match the C# Stopwatch solution equivalent. I tried to search but the information is too broad and I couldn't find an absolute solution.

double PCFreq = 0.0;
__int64 CounterStart = 0;
void StartCounter()
{
    LARGE_INTEGER li;
    if(!QueryPerformanceFrequency(&li))
    std::cout << "QueryPerformanceFrequency failed!\n";
    PCFreq = double(li.QuadPart)/1000.0;
    QueryPerformanceCounter(&li);
    CounterStart = li.QuadPart;
}

double GetCounter()
{
    LARGE_INTEGER li;
    QueryPerformanceCounter(&li);
    return double(li.QuadPart-CounterStart)/PCFreq;
}

As that gives me two different results, I tend to believe the clock. :)

start =  StartCounter()
//some function or for loop
end = GetCounter()
marginPc = end - start;

start = clock();
// ...same
end= clock();
marginClck = end - start;

std::cout<< "Res Pc: " << marginPc << "\r\nRes Clck: " marginClck<< std::endl;

With the clock version I tried both unsigned int and double but the results were still different.

What is the proper method equivalent to the C# Stopwatch?

theB
  • 6,450
  • 1
  • 28
  • 38
Raj Felix
  • 685
  • 5
  • 16
  • 3
    Check out [C++ Cross-Platform High-Resolution Timer](http://stackoverflow.com/questions/1487695/c-cross-platform-high-resolution-timer?lq=1) – Bo Persson Oct 21 '15 at 14:15
  • 2
    You shouldn't expect "some function or for loop" to take the same amount of time if executed twice (e.g. there could be caching side effects making the second run faster); put both clocks around it and run it once, then compare the clock measurements. Any why complain about them being different without giving any measurements with which we can ascertain whether it's significant? Different by how many microsecond? And `QueryPerformanceFrequency` has historically been an unreliable pile of crap. If you have RDTSCP support, could use it directly.... – Tony Delroy Oct 21 '15 at 14:17
  • 1
    @TonyD thanks for commenting," _e.g. there could be caching side effects making the second run faster_ " , how could you have clues to when it's probable / impossible? by the way it wasn't ms difference, the numbers were totally wrong – Raj Felix Oct 21 '15 at 14:31
  • You're doing it wrong. `clock` and the performance counter have way different resolutions. You're not dividing the clock delta by CLOCKS_PER_SEC either while you are dividing the performance counter delta by its frequency, so you're comparing total clock ticks to the time calculated from the performance counter. Also, your function definitions don't match how you use them below. – Rob K Oct 21 '15 at 17:05

2 Answers2

1

Your bug is this. You have StartCounter return CounterStart = li.QuadPart;

But GetCounter returns double(li.QuadPart-CounterStart)/PCFreq.

I.e. one is divided by PCFreq and the other is not. It's not valid to then subtract one from the other.

Ben
  • 34,935
  • 6
  • 74
  • 113
1

clock() gives you the number of milliseconds since the program started. For example, the following program will print a number close to 500:

int main()
{
    Sleep(500);
    cout << clock() << endl;

    /*
    POSIX version:
    std::cout << clock() * 1000.0 / CLOCKS_PER_SEC << std::endl;
    CLOCKS_PER_SEC is 1000 in Windows
    */

    return 0;
}

QueryPerformanceCounter is sort of similar to GetTickCount64, it is based on the time when the computer started. When you do Stop-Watch type subtraction, the results are very close. QueryPerformanceCounter is more accurate. chrono method from @BoPersson's link is also based on QueryPerformanceCounter.

MSDN recommends using QueryPerformanceCounter (QPC) for high resolution stamps:
Acquiring high-resolution time stamps

The same QPC function is used in managed code:

For managed code, the System.Diagnostics.Stopwatch class uses QPC as its precise time basis

This function should have reasonable accuracy:

long long getmicroseconds()
{
    LARGE_INTEGER fq, t;
    QueryPerformanceFrequency(&fq);
    QueryPerformanceCounter(&t);
    return 1000000 * t.QuadPart / fq.QuadPart;
}

The computer clock is usually accurate to +/-1 second per day.

From above link:

Duration          Uncertainty
1 microsecond     ± 10 picoseconds (10-12)
1 millisecond     ± 10 nanoseconds (10-9)
1 second          ± 10 microseconds
1 hour            ± 60 microseconds
1 day             ± 0.86 seconds
1 week            ± 6.08 seconds

To simplify your other function, you can avoid double results. QuadPart is long long, so use that throughout the functions:

long long PCFreq = 0;
long long CounterStart = 0;
void StartCounter()
{
    LARGE_INTEGER li;
    QueryPerformanceFrequency(&li);
    PCFreq = li.QuadPart;
    QueryPerformanceCounter(&li);
    CounterStart = li.QuadPart;
}

long long GetCounter()
{
    if (PCFreq < 1) return 0;
    LARGE_INTEGER li;
    QueryPerformanceCounter(&li);

    //for milliseconds: 1,000
    return  1000 * (li.QuadPart - CounterStart) / PCFreq;

    //for microseconds: 1,000,000
    //return  1000000 * (li.QuadPart - CounterStart) / PCFreq;
}
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
  • i am only learning, i think no one notest this, that i just copy pasted this implementation after using `clock()` which led me to search more acurate example, that code was posted somewhere i am allmost sure it was as an answer here in SO, anyways i do thank you for contributing to my problem with your strate to the point answare, and i just hope that this time i get a working code to test with thanks a lot Barmak! – Raj Felix Oct 21 '15 at 22:31
  • I am not sure about your question. The result from `clock` and `QueryPerformanceFrequency` should be the same for a stop-watch. There are some differences. See updated answer. – Barmak Shemirani Oct 21 '15 at 23:11
  • in return to your confus attempt : https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=7&cad=rja&uact=8&ved=0CEcQFjAGahUKEwjyrc7vpdTIAhXD7RQKHQf_BjQ&url=http%3A%2F%2Fwww.cs.sfu.ca%2F~ashriram%2Fcourses%2F2012%2FCS479%2Fproject%2FTSP%2Fhrtime.h&usg=AFQjCNHELcgs7LwAR-XWp4deVvvBDRpYBg&sig2=AcUtksuaPn73okl5Nn_rzg look for ms if defs cause i got lost there ... see if they say any different – Raj Felix Oct 22 '15 at 00:48
  • by the way thanks again, sure they suppose to be the same , does QPFF as opposed to clock can supply /10 of a milli ? can it say for example result of clock() is 7 ms could QpfF get more accurate and say not realy 7 it's 6.72 ms ? sorry i said tenth so 6.7 – Raj Felix Oct 22 '15 at 00:55
  • i think it is even better i just edit the return value from your answer to be 100k times result instead of 1k and it does give the looks of some reasonable results... looks promissing for small durations ! – Raj Felix Oct 22 '15 at 01:04
  • by the way without to much knowlage, even i could agree that const 1000 is 1 s / 1000ms, and const 1000 allso makes 1ms to 1000nanos... the only variable should be CPUFrq but it's only to do with cpu time rathar elappsedm, meaning the last one should calculate how many instructions you let the cpu do for your code. – Raj Felix Oct 22 '15 at 01:14
  • I found this link https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408%28v=vs.85%29.aspx it looks like c# StopWatch uses QPC too. – Barmak Shemirani Oct 22 '15 at 02:09