{"id":4958,"date":"2016-09-22T20:14:01","date_gmt":"2016-09-22T20:14:01","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/the-three-clocks\/"},"modified":"2023-06-26T12:41:37","modified_gmt":"2023-06-26T12:41:37","slug":"the-three-clocks","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/the-three-clocks\/","title":{"rendered":"The Three Clocks"},"content":{"rendered":"<p>A clock consists of a starting point and a time tick. C++ offers with <span style=\"font-family: courier new,courier;\">std::chrono::system_clock<\/span>, <span style=\"font-family: courier new,courier;\">std::chrono::steady_clock,<\/span> and <span style=\"font-family: courier new,courier;\">std::chrono::high_resolution_clock<\/span> three clocks.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<h2>The clocks<\/h2>\n<p>Because of three different clocks, there is the question: What are the differences?<\/p>\n<ul>\n<li><strong>std::chrono::sytem_clock: <\/strong>This is the system-wide real-time clock (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Wall-clock_time\">wall-clock<\/a>). The clock has the auxiliary functions <span style=\"font-family: courier new,courier;\">to_time_t<\/span> and <span style=\"font-family: courier new,courier;\">from_time_t<\/span> to <a href=\"https:\/\/www.modernescpp.com\/index.php\/time-point\">convert time points into dates.<\/a><\/li>\n<li><strong>std::chrono::steady_clock:&nbsp;<\/strong> Provides as only a clock the guarantee that you can not adjust it. Therefore, <span style=\"font-family: courier new,courier;\">std::chrono::steady_clock<\/span> is the preferred clock to wait for a time duration or until a time point.<\/li>\n<li><strong>std::chrono::high_resolution_clock: <\/strong>This is the clock with the highest accuracy, but it can be a synonym for the clock&#8217;s <span style=\"font-family: courier new,courier;\">std::chrono::system_clock<\/span> or <span style=\"font-family: courier new,courier;\">std::chrono::steady_clock.<\/span><\/li>\n<\/ul>\n<p>The C++ standard provides no guarantee about the clocks&#8217; accuracy, starting point, or valid time range. Typically, the starting point of <span style=\"font-family: courier new,courier;\">std::chrono:system_clock<\/span> is the 1.1.1970, the so-called <a href=\"https:\/\/de.wikipedia.org\/wiki\/Unixzeit\">UNIX-epoch<\/a>. For <span style=\"font-family: courier new,courier;\">std::chrono::steady_clock<\/span>, typically the boot time of your PC.<\/p>\n<h3>Accuracy and Steadiness<\/h3>\n<p>It&#8217;s interesting to know which clocks are steady and which accuracy they provide. You get the answers from the clocks.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ clockProperties.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;chrono&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iomanip&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\n<span style=\"color: #2b91af;\">void<\/span> printRatio(){ \r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"  precision: \"<\/span> &lt;&lt; T::num &lt;&lt; <span style=\"color: #a31515;\">\"\/\"<\/span> &lt;&lt; T::den &lt;&lt; <span style=\"color: #a31515;\">\" second \"<\/span> &lt;&lt; std::endl;\r\n    <span style=\"color: #0000ff;\">typedef<\/span> <span style=\"color: #0000ff;\">typename<\/span> std::ratio_multiply&lt;T,std::kilo&gt;::type MillSec;\r\n    <span style=\"color: #0000ff;\">typedef<\/span> <span style=\"color: #0000ff;\">typename<\/span> std::ratio_multiply&lt;T,std::mega&gt;::type MicroSec;\r\n    std::cout &lt;&lt; std::fixed;\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"             \"<\/span> &lt;&lt; <span style=\"color: #0000ff;\">static_cast<\/span>&lt;<span style=\"color: #2b91af;\">double<\/span>&gt;(MillSec::num)\/MillSec::den &lt;&lt; <span style=\"color: #a31515;\">\" milliseconds \"<\/span> &lt;&lt; std::endl;\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"             \"<\/span> &lt;&lt; <span style=\"color: #0000ff;\">static_cast<\/span>&lt;<span style=\"color: #2b91af;\">double<\/span>&gt;(MicroSec::num)\/MicroSec::den &lt;&lt; <span style=\"color: #a31515;\">\" microseconds \"<\/span> &lt;&lt; std::endl;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n    \r\n    std::cout &lt;&lt; std::boolalpha &lt;&lt; std::endl;\r\n    \r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"std::chrono::system_clock: \"<\/span> &lt;&lt; std::endl;\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"  is steady: \"<\/span> &lt;&lt; std::chrono::system_clock::is_steady &lt;&lt; std::endl;\r\n    printRatio&lt;std::chrono::system_clock::period&gt;();\r\n    \r\n    std::cout &lt;&lt; std::endl;\r\n    \r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"std::chrono::steady_clock: \"<\/span> &lt;&lt; std::endl;\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"  is steady: \"<\/span> &lt;&lt; std::chrono::steady_clock::is_steady &lt;&lt; std::endl;\r\n    printRatio&lt;std::chrono::steady_clock::period&gt;();\r\n    \r\n    std::cout &lt;&lt; std::endl;\r\n    \r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"std::chrono::high_resolution_clock: \"<\/span> &lt;&lt; std::endl;\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"  is steady: \"<\/span> &lt;&lt; std::chrono::high_resolution_clock::is_steady &lt;&lt; std::endl;\r\n    printRatio&lt;std::chrono::high_resolution_clock::period&gt;();\r\n    \r\n    \r\n    std::cout &lt;&lt; std::endl;\r\n    \r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I display in lines 22, 28, and 34 whether each clock is continuous. My job in the function <span style=\"font-family: courier new,courier;\">printRatio<\/span> (lines 7 &#8211; 15) is more challenging. First, I show the accuracy of the clocks in a fraction, and second, in a floating number. Therefore, I use the function template <span style=\"font-family: courier new,courier;\">std::ratio_multiply<\/span> and the constants<span style=\"font-family: courier new,courier;\"> std::kilo<\/span> and <span style=\"font-family: courier new,courier;\">std::mega<\/span> to adjust the units to milliseconds and microseconds. You can get the details on the calculation at compile time at&nbsp;<a href=\"http:\/\/en.cppreference.com\/w\/cpp\/numeric\/ratio\">cppreference.com.<\/a><\/p>\n<p>The output on Linux differs from that on Windows. <span style=\"font-family: courier new,courier;\">std::chrono::system_clock<\/span> is far more accurate on Linux; <span style=\"font-family: courier new,courier;\">std::chrono::high_resultion_clock<\/span> is steady on Windows.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4954\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/clockProperties.png\" alt=\"clockProperties\" style=\"margin: 15px;\" width=\"411\" height=\"426\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/clockProperties.png 411w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/clockProperties-289x300.png 289w\" sizes=\"auto, (max-width: 411px) 100vw, 411px\" \/><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4955\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/clockPropertiesWin.png\" alt=\"clockPropertiesWin\" width=\"477\" height=\"323\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/clockPropertiesWin.png 477w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/clockPropertiesWin-300x203.png 300w\" sizes=\"auto, (max-width: 477px) 100vw, 477px\" \/><\/p>\n<p>Although the C++ standard doesn&#8217;t specify the epoch of the clock, you can calculate it.<\/p>\n<\/p>\n<h3>Epoch<\/h3>\n<p>Thanks to the auxiliary function <span style=\"font-family: courier new,courier;\">time_since_epoch<\/span>, you get how much time has passed since the epoch from each time point.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ now.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;chrono&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iomanip&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">template<\/span> &lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\n<span style=\"color: #2b91af;\">void<\/span> durationSinceEpoch(T dur){\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"     Counts since epoch:  \"<\/span> &lt;&lt; dur.count() &lt;&lt; std::endl;\r\n    <span style=\"color: #0000ff;\">typedef<\/span> std::chrono::duration&lt;<span style=\"color: #2b91af;\">double<\/span>, std::ratio&lt;60&gt;&gt; MyMinuteTick;\r\n    MyMinuteTick myMinute(dur);\r\n    std::cout &lt;&lt; std::fixed;\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"     Minutes since epoch: \"<\/span>&lt;&lt; myMinute.count() &lt;&lt; std::endl;\r\n    <span style=\"color: #0000ff;\">typedef<\/span> std::chrono::duration&lt;<span style=\"color: #2b91af;\">double<\/span>, std::ratio&lt;60*60*24*365&gt;&gt; MyYearTick;\r\n    MyYearTick myYear(dur);\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"     Years since epoch:   \"<\/span> &lt;&lt; myYear.count() &lt;&lt; std::endl;\r\n}\r\n    \r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n    \r\n    std::cout &lt;&lt; std::endl;\r\n    \r\n    std::chrono::system_clock::time_point timeNowSysClock = std::chrono::system_clock::now(); \r\n    std::chrono::system_clock::duration timeDurSysClock= timeNowSysClock.time_since_epoch();\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"std::chrono::system_clock: \"<\/span> &lt;&lt; std::endl;\r\n    durationSinceEpoch(timeDurSysClock);\r\n    \r\n    std::cout &lt;&lt; std::endl;\r\n     \r\n    <span style=\"color: #0000ff;\">auto<\/span> timeNowStClock = std::chrono::steady_clock::now(); \r\n    <span style=\"color: #0000ff;\">auto<\/span> timeDurStClock= timeNowStClock.time_since_epoch();\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"std::chrono::steady_clock: \"<\/span> &lt;&lt; std::endl;\r\n    durationSinceEpoch(timeDurStClock);\r\n    \r\n    std::cout &lt;&lt; std::endl;\r\n    \r\n    <span style=\"color: #0000ff;\">auto<\/span> timeNowHiRes = std::chrono::high_resolution_clock::now(); \r\n    <span style=\"color: #0000ff;\">auto<\/span> timeDurHiResClock= timeNowHiRes.time_since_epoch();\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"std::chrono::high_resolution_clock: \"<\/span> &lt;&lt; std::endl;\r\n    durationSinceEpoch(timeDurHiResClock);\r\n    \r\n    std::cout &lt;&lt; std::endl;\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The variables <span style=\"font-family: courier new,courier;\">timeDurSysClock<\/span> (line 24), <span style=\"font-family: courier new,courier;\">timeNowStClock<\/span> (line 31), and <span style=\"font-family: courier new,courier;\">timeNowHiResClock<\/span> (Zeile 38) hold for each clock, how much time has passed since the starting point of the clock. When I use no automatic type deduction with <span style=\"font-family: courier new,courier;\">auto<\/span>, explicit types of the time point and time duration are extremely verbose to write. In the function durationSinceEpoch (lines 7 &#8211; 17), I show the time duration in different resolutions. First, I display the number of time ticks (line 9), then the number of minutes (line 13), and at the end of the years (line 16) since the epoch, all depending on the used clock. I ignore leap years for simplicity, and my year has 365 days.<\/p>\n<p>The results are different on Linux and Windows.<\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4956\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/now.png\" alt=\"now\" style=\"margin: 15px;\" width=\"411\" height=\"381\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/now.png 411w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/now-300x278.png 300w\" sizes=\"auto, (max-width: 411px) 100vw, 411px\" \/><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-4957\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/nowWin.PNG\" alt=\"nowWin\" width=\"517\" height=\"287\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/nowWin.PNG 517w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/09\/nowWin-300x167.png 300w\" sizes=\"auto, (max-width: 517px) 100vw, 517px\" \/><\/p>\n<p>To draw the right conclusion, I must mention that my Linux PC runs for about <span id=\"transmark\"><\/span>5 hours (305 minutes) and my Windows PC for more than 6 hours (391 minutes).<\/p>\n<p><span style=\"font-family: courier new,courier;\">std::chrono::system_clock<\/span> and <span style=\"font-family: courier new,courier;\">std::chrono::high_resolution_clock<\/span>&nbsp;have on Linux the UNIX-epoch as starting point. The starting point of <span style=\"font-family: courier new,courier;\">std::chrono::steady_clock <\/span>is the boot time of my PC. The difference between Linux and Windows is <span style=\"font-family: courier new,courier;\">std::high_resolution_clock.<\/span> On Linux, the <span style=\"font-family: courier new,courier;\">std::chrono::system_clock<\/span> is internally used; on Windows, the <span style=\"font-family: courier new,courier;\">std::chrono::steady_clock<\/span> is internally used.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>That is not the end of the story about the new time library. With the component&#8217;s time point and time duration, you can put a thread for an absolute or relative time to sleep. The details will follow in the <a href=\"https:\/\/www.modernescpp.com\/index.php\/sleep-and-wait\">next post.<\/a> &nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A clock consists of a starting point and a time tick. C++ offers with std::chrono::system_clock, std::chrono::steady_clock, and std::chrono::high_resolution_clock three clocks.<\/p>\n","protected":false},"author":21,"featured_media":4954,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[369],"tags":[453],"class_list":["post-4958","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-multithreading-application","tag-time"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4958","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=4958"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4958\/revisions"}],"predecessor-version":[{"id":6944,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/4958\/revisions\/6944"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/4954"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=4958"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=4958"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=4958"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}