<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="113411" data-post-id="113411">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="garazdawi" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/garazdawi/120/5853_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  garazdawi
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Erlang Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Sleeping in poll or on a futex already supports nanosecond resolution if the platform supports it. We use it when a scheduler decides that it needs to sleep a fraction of a millisecond before the timer would fire. i.e. timer should fire at 5ms, but scheduler decides to sleep at 2.545 ms.</p>
<p>What would need to be done is to change the resolution of the timer wheel that dispatches timeouts, and of course expose the APIs.</p>
<p>Regarding which API would be the best to use, I’ve not really experimented all that much. clock_gettime in virtualized environments does have problems, but when running native it usually works good enough.</p>
<p>I think that in general though if you need nanosecond accuracy of your timers, linux may not be the operating system to use.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="113411" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/sub-millisecond-timer-precision/19618/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-113411" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="113411"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="113413" data-post-id="113413">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="massimo" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/massimo/120/5555_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  massimo
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="12433412" data-post="11" data-topic="19618">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/12433412/48/13687_2.png" class="avatar"> 12433412:</div>
<blockquote>
<p><code>timerfd_create</code></p>
</blockquote>
</aside>
<p>When I was writing <code>micro_timer</code> first thing I tried was a C implementation of the <code>sleep</code> function.</p>
<p>I’ve tried almost everything, from setting a timeout to <code>select</code> and <code>kevent</code> to Posix <code>timer_*</code> functions, none of them worked reliably.</p>
<p>From my measurements, without spinlocks, you can’t get consistent sub-millisecond timings, to the point that waiting 1 million times for 1 microsecond (should be a second) takes almost 2 seconds.</p>
<p>The graph below shows the average difference between the timeout and the time it actually took to return.<br>
The results are computed from 50 thousands samples, the timeout was set randomly from 1 to 65.535 microseconds (65ms).<br>
The average deviation for the C implementation is 2.509ms, 11.4%.<br>
But the worst case is 10x off.</p>
<p>The three implementation tested are</p>
<ul>
<li>C uses <code>select</code> with a timeout</li>
<li>Ex0 waits timeout - 1ms and loops for a maximum of 1ms</li>
<li>Ex1 waits timeout - 2ms and loops for a maximum of 2ms</li>
</ul>
<p>If you don’t need consistent absolute precision, any of the C implementations is good enough and they roughly work the same way.</p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/2X/9/91514aae3b38bcc3200a5286309f3242668e5e2d.png" data-download-href="https://forum.elixirforum.com/uploads/default/91514aae3b38bcc3200a5286309f3242668e5e2d" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/optimized/2X/9/91514aae3b38bcc3200a5286309f3242668e5e2d_2_690x431.png" alt="image" data-base62-sha1="kJxoNj8QOW2s0ZGUMbuxM2PXHc1" width="690" height="431" srcset="https://forum.elixirforum.com/uploads/default/optimized/2X/9/91514aae3b38bcc3200a5286309f3242668e5e2d_2_690x431.png, https://forum.elixirforum.com/uploads/default/optimized/2X/9/91514aae3b38bcc3200a5286309f3242668e5e2d_2_1035x646.png 1.5x, https://forum.elixirforum.com/uploads/default/optimized/2X/9/91514aae3b38bcc3200a5286309f3242668e5e2d_2_1380x862.png 2x" data-dominant-color="DDEBEF"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">1822×1139 38.7 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="113413" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/sub-millisecond-timer-precision/19618/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-113413" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="113413"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="113436" data-post-id="113436">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="12433412" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/12433412/120/13687_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  12433412
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote group-Erlang-Core-Team" data-username="garazdawi" data-post="12" data-topic="19618">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/garazdawi/48/5853_2.png" class="avatar"> garazdawi:</div>
<blockquote>
<p>What would need to be done is to change the resolution of the timer wheel that dispatches timeouts, and of course expose the APIs.</p>
</blockquote>
</aside>
<p>The <a href="https://github.com/erlang/otp/blob/maint/erts/emulator/beam/time.c" rel="noopener nofollow ugc">timer.c</a> is very interesting reading indeed. I am tempted to hack the timeout facility and bump the slot length to 1μs  and see what it does (besides breaking all time-related APIs <img src="https://forum.elixirforum.com/images/emoji/apple/smile.png?v=15" title=":smile:" class="emoji" alt=":smile:" loading="lazy" width="20" height="20">). My guess is that the timer wheel would introduce quite some load on the CPU compared to 1ms slots but I might be wrong.</p>
<p>I have no need for <em>ns</em> precision. Tens of microseconds are fine for my case. Stepping down to milliseconds would, however, introduce an inherent throughput issue as timeouts are part of nearly every operation within the app.</p>
<p>Again, many thanks for great pointers!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="113436" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/sub-millisecond-timer-precision/19618/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-113436" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="113436"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="113437" data-post-id="113437">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="12433412" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/12433412/120/13687_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  12433412
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="massimo" data-post="13" data-topic="19618">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/massimo/48/5555_2.png" class="avatar"> massimo:</div>
<blockquote>
<p>If you don’t need consistent absolute precision, any of the C implementations is good enough and they roughly work the same way.</p>
</blockquote>
</aside>
<p>This looks like a load of context switching going on. They are usually behind the <code>clock_gettime</code> call. Before setting a timeout, the current time is needed to calculate the timeout timestamp (e.g. <code>nanosleep</code> will always call that function first). I have seen online benchmarks that revealed the strong correlation between context switching and the lag. Given you can hardware-bind and dedicate a single core to the timer process, it should be possible to achieve outstanding results.</p>
<p>I actually found a way around this setting an <em>interval</em> on the timer and handling the <em>SIGEV_SIGNAL</em> interrupt. The clock_gettime calls are avoided and the performance is much more consistent. Yet, such repetitive timer is rarely useful I’d guess…</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="113437" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/sub-millisecond-timer-precision/19618/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-113437" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="113437"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>