简体   繁体   中英

Where does the time from `std::chrono::system_clock::now().time_since_epoch()` come from and can it block if accessed from multiple threads?

Where does std::chrono::system_clock::now().time_since_epoch() come from? That is, is it a direct interface with a crystal oscillator (physical component)?

If it is a crystal oscillator, is there one per core or one for all cores?

If there is one oscillator for all cores, can it block threads if multiple threads access it at the exact same time (low latency environment)?

If there is a crystal oscillators for each core how are they all synchronised?

C++ Standard does not care about how system_clock::now() gets implemented. It merely specifies

Returns a time_point object representing the current point in time.

A typical C++ standard library implementation would rely on the underlying OS system call to get the actual system clock value to construct the time_point object.

In terms of hardware implementation you will need to take hardware architecture into consideration. But typically maintenance cost for system clock is always there, no matter how many processes / threads are reading it. And system clock acquiring are implemented as a lightweight routine which will not result in thread block and will not become the performance bottleneck in a multithreaded program.

Besides, std::chrono::system_clock::now().time_since_epoch() is a simple observer method which only returns the embedded duration object inside the time_point object returned by std::chrono::system_clock::now() , which involves only C++ struct copying.

The standard specifies std::chrono::system_clock as follows:

23.17.7.1 Class system_clock [time.clock.system]

Objects of class system_clock represent wall clock time from the system-wide realtime clock.

This has multiple implications. First, timepoints from this clock can be converted to and from time_t time via std::chrono::system_clock::to_time_t and std::chrono::system_clock::from_time_t hinting that the clock represents some sort of physical time. Secondly, the clock is specified as "system-wide" which means that all processes should retrieve the same time_point values from this clock.

In practice, this means that this clock is most often implemented with calls to OS specific functions that retrieve some sort of time, as you'd for example see in your taskbar.

Note that it is unspecified if this clock is_steady . This means that timepoints from this clock do not have to always advance. You could get an earlier timepoint even if the call occured later in physical time. This could happen if the user for example adjusted the clock through some OS setting.

What is closer to what you are describing is std::chrono::steady_clock :

23.17.7.2 Class steady_clock [time.clock.steady]

Objects of class steady_clock represent clocks for which values of time_point never decrease as physical time advances and for which values of time_point advance at a steady rate relative to real time.

We have two requirements mentioned. First, the clock has to be monotonic, so time can never "run backwards". Secondly, the clock is steady, so every tick of this clock should take the same amount of physical time.

It feels natural to implement this clock with some sort of hardware counter like a cycle counter. But be careful: this clock does not have to be system wide. This is, so that a value can eg be fetched from the CPU it is currently executing, even if there are perhaps other CPUs present with different counters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM