[erlang-questions] writing a delay loop without now()

Per Hedeland <>
Sat Feb 28 12:58:25 CET 2009


tsuraan <> wrote:
>
>My results, on Linux 2.6.28 (vanilla) and a core2 duo at 3GHz:
>
>Erlang (BEAM) emulator version 5.6.1 [source] [smp:2]
>[async-threads:0] [hipe] [kernel-poll:false]
>
>Eshell V5.6.1  (abort with ^G)
>1> c(test).
>{ok,test}
>2> erlang:statistics(wall_clock),test:time(5000000),erlang:statistics(wall_clock).
>{24784,3960}

Mighty strange - with Linux, the exact same Erlang runtime, and actually
exact same HW too, I still get perfect results:

2> erlang:statistics(wall_clock),test:time(5000000),erlang:statistics(wall_clock).
{93876,5000}

The kernel is different though ("2.6.20-1.2320.fc5smp"), probably glibc
too, but I have a hard time believing that either of those is the cause.
I don't suppose that you run some primitive time-keeping app that keeps
whacking the system time around? (The above system runs NTP.)

What number do you get with the loop-counting version I posted earlier
(time2/1 reposted below)? I get numbers like 4559687, which is
uncomfortably close to 1 call per microsecond but still just below - I
think it would have to be some 25% faster on your system to produce the
above result. I guess it's possible even if unlikely...

If you do get just about 5000000 (it can never be more), maybe you could
try the "twiddle" version (time3/1 below) too?

--Per

4> erlang:statistics(wall_clock),{test:time2(5000000),erlang:statistics(wall_clock)}.
{{4559687,5000000},{204001,5001}}

time2(N) -> time2(N, now(), 0).
time2(N, Start, C) ->
    case timer:now_diff(now(), Start) of
        M when M >= N -> {C, M};
        _ -> time2(N, Start, C+1)
    end.

time3(N) -> time3(N, now(), 0, [0]).
time3(N, Start, C, X) ->
    case timer:now_diff(now(), Start) of
        M when M >= N -> {C, M};
        _ -> time3(N, Start, C+1, twiddle(X))
    end.

twiddle(X) ->
    [hd(X)|[Y*Y || Y <- lists:duplicate(5, 12345678901234567890123456789)]].



More information about the erlang-questions mailing list