100ns resolution clock

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
poby
Posts: 24
Joined: Wed Sep 21, 2016 9:39 am

100ns resolution clock

Post by poby »

I want to implement a clock with 100ns resolution for file timestamping etc and have been thinking of the most optimal way to do it. I'm using lapic/ioapic and hpet in legacy mode. This is what I've come up with:

1. Setup a periodic timer in HPET to trigger at rollover.

2. During HPET initialisation, wait to enable it until the RTC updates. i.e. Poll the RTC status until it updates, then start the HPET with the main counter at zero.

3. Convert the RTC datetime to a 64 bit number being the nanoseconds since year 2000. Store this.

4. When the HPET timer triggers, add the HPET count to the stored count as nanoseconds.

Now when I want the current datetime in ns, I read the stored value, and add the current main counter value (after converting to ns).
Is this a reasonably efficient way to do it? I want to avoid expensive io ports in favor of reading the MMIO of the HPET main counter. Is there a better way?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: 100ns resolution clock

Post by Brendan »

Hi,
poby wrote:Now when I want the current datetime in ns, I read the stored value, and add the current main counter value (after converting to ns).
Is this a reasonably efficient way to do it? I want to avoid expensive io ports in favor of reading the MMIO of the HPET main counter. Is there a better way?
I'd use the CPU's time stamp counter to avoid MMIO where possible, with HPET only used to keep TSC in sync and/or if TSC can't be used (e.g. CPU in deep sleep). Note that for access times RAM is slow compared to CPU (and CPU's caches) and MMIO is slow compared to RAM (and IO ports are slow compared to MMIO).

I'd also go for 1 ns precision (which doesn't imply 1 ns accuracy), partly because it's possible to get better than 1 ns precision (and better than 1 ns accuracy) from modern TSC anyway; and partly because I'd use the same "nanoseconds since 2000" for everything (including "nanosleep()", accounting for how much time tasks consumed, etc). Note: "unsigned 64-bit nanoseconds since 2000" is enough to cover dates/times from 2000 to 2584.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
MichaelFarthing
Member
Member
Posts: 167
Joined: Thu Mar 10, 2016 7:35 am
Location: Lancaster, England, Disunited Kingdom

Re: 100ns resolution clock

Post by MichaelFarthing »

And how do you record actvity within a leap second?

[Only joking!]
poby
Posts: 24
Joined: Wed Sep 21, 2016 9:39 am

Re: 100ns resolution clock

Post by poby »

Brendan wrote:Hi,
I'd use the CPU's time stamp counter to avoid MMIO where possible, with HPET only used to keep TSC in sync and/or if TSC can't be used (e.g. CPU in deep sleep). Note that for access times RAM is slow compared to CPU (and CPU's caches) and MMIO is slow compared to RAM (and IO ports are slow compared to MMIO).

I'd also go for 1 ns precision (which doesn't imply 1 ns accuracy), partly because it's possible to get better than 1 ns precision (and better than 1 ns accuracy) from modern TSC anyway; and partly because I'd use the same "nanoseconds since 2000" for everything (including "nanosleep()", accounting for how much time tasks consumed, etc). Note: "unsigned 64-bit nanoseconds since 2000" is enough to cover dates/times from 2000 to 2584.
Thanks a bunch! I was under the impression the TSC could vary but after reading your response I did some checking and quickly discovered modern processors have an invariant TSC. I've followed your suggestion and implemented a 1 ns resolution timestamp using the TSC and it's way better than using the HPET of course. After synchronising at startup, any time I need a ns resolution time, it's only a few instructions needed and no MMIO reads.
Post Reply