C measures program running time and cpu USES time instance methods

  • 2020-05-24 06:00:43
  • OfStack

What I want to point out here is that the cpu time used to run a program is not the same as the actual running time. Attached are the following:


private void ShowRunTime()
  {
   TimeSpan ts1 = Process.GetCurrentProcess().TotalProcessorTime;
   Stopwatch stw = new Stopwatch();
  stw.Start();
  int Circles = 1000;
   for (int i = 0; i < Circles; ++i)
  {
  }
  double Msecs = Process.GetCurrentProcess().TotalProcessorTime.Subtract(ts1).TotalMilliseconds;
  stw.Stop();
    Console.WriteLine(string.Format(" cycles :{0} CPU time ( ms )={1}  The actual time ( ms )={2}", Circles, Msecs, stw.Elapsed.TotalMilliseconds, stw.ElapsedTicks));
  Console.WriteLine(string.Format("1 tick = {0} ms ", stw.Elapsed.TotalMilliseconds / stw.Elapsed.Ticks));
 } 

The program output is as follows:
Number of cycles :1000 CPU time (milliseconds)=50.072 actual time (milliseconds)=666.9071
1 tick = 0.0001 ms

It can be seen that in this example, there is a large gap between the two, and the reasons are as follows:

1) Windows is a multitasking operating system, which polls and allocates cpu time according to the thread. That is, one program may be deprived of cpu resources in the middle of its operation for other programs to run.
2) the program itself will have a waiting process that does not occupy cpu's time. The wait may be active in our program, such as starting a process and waiting for the process to end. Or perhaps we don't realize that, as in the example of the Console.WriteLine method, we assume that it internally performs a series 1 of asynchronous I/O operations and then waits for the operation to complete, which does not take up the calling process's cpu time, but consumes a lot of wait time.
Conclusion:
1) the performance should be measured by the program running time, of course, cpu time should also be used as a reference. If there is a big difference between the two, we need to consider why this happens.
2).Net class Stopwatch can be accurate to 1/10000 milliseconds, basically meeting the measurement accuracy.


Personal arrangement:
When the Elapsed and ElapsedMilliseconds properties are called, the QueryPerformanceFrequency() function in kernel32 is called internally to obtain the frequency of the high precision timer supported by the processor, and the acquired time difference is corrected with this number. Finally, the Elapsed property returns a new TimeSpan object. This high-precision calculation (correction) is not performed when obtaining the ElapsedTicks attribute. But 1 is generally not that much of an error. The Elapsed and ElapsedMilliseconds properties are recommended if precise timing is required or if the amount of test data is particularly large.

There are questions:
After the test, I found that there was no conclusion like the following. I have replied to the original author, but I haven't received a reply yet. For those of you who want to know why. thank you
From an internal implementation point of view, when StopWatch.IsHighresolution = true, StopWatch.Elapsed.Ticks should be equal to StopWatch.ElapsedTicks times frequency (frequency constant). On the contrary, these two Numbers should be equal when IsRunning is true. So it should be StopWatch.Elapsed.Ticks is bigger.


Related articles: