[erlang-questions] I'm having a SNAFU moment: timer:sleep/1

Darach Ennis darach@REDACTED
Mon Jan 12 17:23:25 CET 2015


Hi guys,

+1.

And if you consider a loop consider erlang:yield as Sergej recommended.

If your use case can tolerate a little slew or skew then using a timer or
erlang:send_after instead might be a pleasant sufficiency.

If your use case is deadline critical or hard real-time oriented then
perhaps
you might be interested in work being done by Peer Strizinger in the
embedded
space. He has spoken about this at EUC and Codemesh:

http://www.codemesh.io/codemesh2014/peer-stritzinger
http://www.erlang-factory.com/euc2014/peer-stritzinger

Peer has ported Erlang to an RTEMS and this may also be of interest:

http://www.grisp.org/

Cheers,

Darach.

On Mon, Jan 12, 2015 at 4:13 PM, Sergej Jurecko <sergej.jurecko@REDACTED>
wrote:

> There is no other solution other than the two provided. An endless loop
> without sleep, or an external program (or driver).
>
>
> Sergej
>
>
> On 12 Jan 2015, at 17:03, Roberto Ostinelli <roberto@REDACTED> wrote:
>
> Hi Jesper,
> I was expecting a more precise timer, that is all. :)
> Thank you for your input.
>
> So: how can someone execute an action every 1ms?
>
> Best,
> r.
>
> On Mon, Jan 12, 2015 at 12:43 PM, Jesper Louis Andersen <
> jesper.louis.andersen@REDACTED> wrote:
>
>> Hi Roberto,
>>
>> I'm not sure what you would expect here. timer:sleep/1 has an
>> implementation like this:
>>
>> sleep(T) ->
>>     receive
>>     after T -> ok
>>     end.
>>
>> which is what other people told you also. In general, such timing
>> constructs have no guarantee about when they will fire, only that they will
>> fire after the time has elapsed. So what you are seeing is somewhat
>> expected behaviour. The more fine-grained and the more timers you have, the
>> less precise things will get. In a way, this is one of the properties which
>> makes Erlang a soft-realtime system and not a hard-realtime one, although
>> the precise definition of soft/hard realtime are subtly different.
>>
>> I believe there were some effort being made by the OTP team to address
>> lock contention around the timer wheel, so the code might change behaviour
>> by quite a lot in the future. It might even have to get worse for
>> single-process timers in order to become better for multi-process timers.
>>
>>
>> On Mon Jan 12 2015 at 12:20:15 PM Roberto Ostinelli <roberto@REDACTED>
>> wrote:
>>
>>> Indeed. From very basic try-outs:
>>>
>>> 1>  test:sleep_periodical(6, 1000).
>>> Finished in 6022381 microseconds.
>>> ok
>>> 2>  test:sleep_periodical(12, 500).
>>> Finished in 6042683 microseconds.
>>> ok
>>> 3>  test:sleep_periodical(24, 250).
>>> Finished in 6062096 microseconds.
>>> ok
>>> 4>  test:sleep_periodical(48, 125).
>>> Finished in 6133169 microseconds.
>>> ok
>>> 5> test:sleep_periodical(96, 62).
>>> Finished in 6320419 microseconds.
>>> ok
>>> 6> test:sleep_periodical(192, 31).
>>> Finished in 6492321 microseconds.
>>> ok
>>> 7> test:sleep_periodical(384, 16).
>>> Finished in 7327693 microseconds.
>>> ok
>>>
>>> So it somewhat is ok until we get in the 125ms range.
>>>
>>>
>>>
>>> On Mon, Jan 12, 2015 at 12:12 PM, Sergej Jurečko <
>>> sergej.jurecko@REDACTED> wrote:
>>>
>>>> timer:sleep is not even remotely as accurate for those low numbers. It
>>>> can not go lower than 20ms or so from what i remember.
>>>>
>>>> I have had this issue once when I needed low interval for timer. I used
>>>> an external c app which printed to stdout every 5ms. I dont think there is
>>>> any way in erlang to get a timer that low.
>>>>
>>>> Sergej
>>>> On Jan 12, 2015 11:46 AM, "Roberto Ostinelli" <roberto@REDACTED>
>>>> wrote:
>>>>
>>>>> Additionally:
>>>>>
>>>>> 6> test:sleep_periodical(1000, 1).
>>>>> Finished in 1999097 microsecond
>>>>>
>>>>> So:
>>>>>
>>>>>    - Looping 1,000 times and sleeping 1 ms each time takes 2.00
>>>>>    seconds (instead of 1).
>>>>>
>>>>> Looks like it's ms related, not total count.
>>>>>
>>>>> Best,
>>>>> r.
>>>>>
>>>>>
>>>>>
>>>>> On Mon, Jan 12, 2015 at 11:40 AM, Roberto Ostinelli <
>>>>> roberto@REDACTED> wrote:
>>>>>
>>>>>> Dear list,
>>>>>> I've probably missed out something since I'm not understanding what
>>>>>> is going here.
>>>>>>
>>>>>> I'm basically just trying to send messages periodically, though I
>>>>>> found out that I wasn't seeing the behavior that I was expecting. It looks
>>>>>> like the timer has some erratic behavior.
>>>>>>
>>>>>> I've stripped out the code to the bare minimum and it looks like this:
>>>>>>
>>>>>> -module(test).
>>>>>> -export([sleep_periodical/2]).
>>>>>> -export([sleep_loop/2]).
>>>>>>
>>>>>> sleep_periodical(Num, IntervalMs) ->
>>>>>> {Time, _Value} = timer:tc(?MODULE, sleep_loop, [Num, IntervalMs]),
>>>>>> io:format("Finished in ~p microseconds.~n", [Time]).
>>>>>>
>>>>>> sleep_loop(Num, IntervalMs) ->
>>>>>> SleepFun = fun(_) -> timer:sleep(IntervalMs) end,
>>>>>> lists:foreach(SleepFun, lists:seq(1, Num)).
>>>>>>
>>>>>>
>>>>>> When I run this code, I see the following:
>>>>>>
>>>>>> Erlang/OTP 17 [erts-6.3] [source] [64-bit] [smp:8:8]
>>>>>> [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
>>>>>>
>>>>>> Eshell V6.3  (abort with ^G)
>>>>>> 1> c(test).
>>>>>> {ok,test}
>>>>>> 2> test:sleep_periodical(1000, 10).
>>>>>> Finished in 12257397 microseconds.
>>>>>> ok
>>>>>> 3> test:sleep_periodical(2000, 10).
>>>>>> Finished in 24518070 microseconds.
>>>>>> ok
>>>>>> 4> test:sleep_periodical(10000, 1).
>>>>>> Finished in 20000280 microseconds.
>>>>>> ok
>>>>>> 5> test:sleep_periodical(20000, 1).
>>>>>> Finished in 40000685 microseconds.
>>>>>> ok
>>>>>>
>>>>>> So:
>>>>>>
>>>>>>    - Looping 1,000 times and sleeping 10 ms each time takes 12.26
>>>>>>    seconds (instead of 10).
>>>>>>    - Looping 2,000 times and sleeping 10 ms each time takes 24.52
>>>>>>    seconds (instead of 20).
>>>>>>    - Looping 10,000 times and sleeping 1 ms each time takes 20.00
>>>>>>    seconds (instead of 10).
>>>>>>    - Looping 20,000 times and sleeping 1 ms each time takes 40.00
>>>>>>    seconds (instead of 20).
>>>>>>
>>>>>> Up to 10,000 times it takes 12,16% (1/8) more time, from 10,000 times
>>>>>> it takes 100% (double).
>>>>>>
>>>>>> Can some kind soul explain what I'm doing wrong here and how to
>>>>>> achieve the desired results?
>>>>>>
>>>>>> I'm on OSX, Erlang 17.4.
>>>>>>
>>>>>> Help! ^^_
>>>>>> r.
>>>>>>
>>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> erlang-questions mailing list
>>>>> erlang-questions@REDACTED
>>>>> http://erlang.org/mailman/listinfo/erlang-questions
>>>>>
>>>>>
>>> _______________________________________________
>>> erlang-questions mailing list
>>> erlang-questions@REDACTED
>>> http://erlang.org/mailman/listinfo/erlang-questions
>>>
>>
>
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150112/09c204cc/attachment.htm>


More information about the erlang-questions mailing list