C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  01.05.2010 — Update World C++: Сборник GPL QT исходников
  15.12.2007 — Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Windows 2003, ASP.NET 2.0
бесплатный и от 80 руб./мес

   Отправить письмо
Кулабухов Артем, Беларусь

 HighResClock - C# High Resolution Clock Class / General / C#


The DateTime class represents times with 100ns resolution; it represents times in ticks, and each tick is 100ns.  However successive calls to DateTime.Now won't return different numbers closer than 10ms or so, which is apparently the resolution of the operating system's software clock.  This C# HighResClock class provides access to Windows' Kernel32.dll high resolution clock function QueryPerformanceCounter which accesses the system's high resolution performance counter. This is motivated by the need to have higher resolution than .Net's DateTime.Now. The effective resolution of HighResClock on a P4 1.4GHz is about 10us.

This is based on a C/C++ sample on MSDN. This class is part of the RTools.Util assembly.

Using the code

HighResClock can't be instantiated; it is a utility class which has only static methods and properties.  It's not a timer or a time/duration representation (DateTime and TimeSpan are great for that), it's a utility class that provides higher resolution clock access. It provides a Now property which works like DateTime.NowHighResClock.Now calls the high resolution clock function, builds a DateTime with the result, and returns it.  So you can use it just like you use DateTime.Now for timing.

HighResClock does a calibration to determine effective clock resolution and function call overhead time, which are static fields. This has a static constructor which calls Calibrate(). Calibrate() temporarily boosts the calling process and thread priority to avoid being affected by other processes/threads.  The CalcTimeSpan() methods adjust for the function call overhead time calculated during Calibrate(), but Now, NowTicks, etc do not.

It's relatively expensive to call HighResClock.Now, compared to DateTime.Now. That's the tradeoff for higher resolution times.

The following code shows an easy way to use HighResClock.Now just like DateTime.Now.  Note that this code does not adjust the duration for the overhead in the high resolution clock reads:

DateTime startTime = HighResClock.Now;
// do something you want to time here
TimeSpan duration = HighResClock.Now - startTime;
Console.WriteLine("Duration: {0}ms", duration.TotalMilliseconds);

The following code uses HighResClock's duration calculation, which compensates for the overhead in the high resolution clock reads:

DateTime startTime = HighResClock.Now;
// do something you want to time here
TimeSpan duration = HighResClock.CalcTimeSpan(startTime);
Console.WriteLine("Duration: {0}ms", duration.TotalMilliseconds);

Points of Interest

Evidently the operating system's software clock is updated by an interrupt (IRQ0) generated about every 10ms (so at 100Hz) by the Programmable Interrupt Controller, which is triggered by the Programmable Interval Timer.  The operating system's IRQ0 Interrupt Service Handler increments the clock value.  The software clock is initialized at startup by reading the motherboard clock.

The CPU, on the other hand, has a clock cycle counter called the "time-stamp counter" which is a 64-bit register.  The CPU sets this to 0 on reset, and increments it every clock cycle.  The IA-32 instruction RDTSC (read time-stamp counter) reads this value into general purpose registers where other instructions can access it. 

Between the two of these clocks, there's Kernel32.dll's "high performance counter" which QueryPerformanceCounter uses. On my 1.4 GHz system the high performance counter has a frequency of about 3.6 MHz.  So the high performance counter is updated about every 400 cpu clock cycles.


January 19, 2003  - First submission