<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On 3 Jul 2018, at 10:45 am, <a href="mailto:amindfv@gmail.com" class="">amindfv@gmail.com</a> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="content-type" content="text/html; charset=utf-8" class=""><div dir="auto" class=""><div class=""></div><div class="">Vivid has combinators to schedule music with sample-accurate timing (it's as simple as prepending e.g. "doScheduledIn 0.2" to any VividAction, where 0.2 is 0.2 seconds from now - everything will be precise relative to that start time). "doScheduledAt" is another useful one. You can also write to a file with precise timing by prepending e.g. 'writeNRT "foo.wav”'.</div></div></div></blockquote><div><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="auto" class=""><div class="">Still, I'd be curious to know the more-general answer to the question of how accurate we can expect forkIO and threadDelay to be, under normal load. E.g. how often/by how much does threadDelay take longer than needed to wake? To my ears and a few quick tests it's usually surprisingly good.</div></div></div></blockquote><div><br class=""></div><div>The question here is somewhat unrelated to the statement above. Audio streams are buffered and are consumed (and thus played back) by the audio hardware which has its own clock. Ensuring that samples are played at the correct time with respect to each other is trivial as you just need to write them into the audio buffer at the correct time. Even if there is a 10ms delay between a user pressing a key and the sample playing, most humans will perceive those actions as simultaneous.</div><div><br class=""></div><div>For the second question about forkIO and threadDelay, the I was working on the Repa data parallel library a few years ago (~2013) I did some testing and the time to wake up a GHC green thread on a separate OS process was in the order of 200 microseconds. Note that this is to wake up a OS process on a separate core. The time to communicate to another process via a MVar should be much shorter. The time to wake up a process is also affected by whether you’ve set the core affinity — so that a particular GHC execution capability is bound to a particular OS process / hardware core.</div><div><br class=""></div><div>See S5.1.1 of the following paper (on page 8)</div><div><a href="http://benl.ouroborus.net/papers/2012-guiding/guiding-Haskell2012.pdf" class="">http://benl.ouroborus.net/papers/2012-guiding/guiding-Haskell2012.pdf</a></div><div><br class=""></div><div>This includes thread scope diagrams showing the delay between forking a computation and it actually starting.</div><div><br class=""></div><div>Ben.</div><div><br class=""></div></div></body></html>