Dirty CPU scheduler and pure Erlang code

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Dirty CPU scheduler and pure Erlang code

Michaël COQUARD
Hi,

I try to understand how the processes are scheduled on the dirty schedulers.

As I understand, the dirty schedulers are meant to execute uninterruptible native code to avoid blocking the standard schedulers (and other Erlang
processes) for a long time.

I noticed the majority of all memory allocations are scheduled on the dirty schedulers: mmap(), munmap() and mremap() calls from the mseg_alloc and
sys_alloc

Now, consider the following code:
-module(foo).
-compile([export_all,nowarn_export_all]).

loop_reverse_erl() ->
     L = lists:seq(1,1000000),
     loop_reverse_erl(L).

loop_reverse_erl(L) ->
     my_reverse(L,[]),
     loop_reverse_erl(L).

% vanilla reverse written in pure Erlang from efficiency_guide.erl
my_reverse([H|T], Acc) -> my_reverse(T, [H|Acc]);
my_reverse([], Acc) -> Acc.

When I launch the loop (foo:loop_reverse_erl().) from the shell, I see an activity on one of a dirty scheduler thread (with top -H -p <pid of beam.smp>)

The dirty scheduler doesn't do anything on a simple infinite loop like this
loop_reverse_erl(L) ->
     loop_reverse_erl(L).

I was expecting only native functions (BIFs / NIFs) are executed on the dirty schedulers.

Is it the expected behavior ? If yes, which conditions trigger the choice of the "dirty" or "normal" scheduler ?

OS: Linux RHEL 7
Erlang version: OTP/21 erts-10.0 (same on OTP/20)

Michael
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Dirty CPU scheduler and pure Erlang code

Peti Gömöri-2
Hi Michael,

With the module `msacc` you can get more info about what the dirty scheduler is busy with. For example it can do garbage collection too.

On Wed, Sep 19, 2018 at 5:19 PM, Michaël COQUARD <[hidden email]> wrote:
Hi,

I try to understand how the processes are scheduled on the dirty schedulers.

As I understand, the dirty schedulers are meant to execute uninterruptible native code to avoid blocking the standard schedulers (and other Erlang processes) for a long time.

I noticed the majority of all memory allocations are scheduled on the dirty schedulers: mmap(), munmap() and mremap() calls from the mseg_alloc and sys_alloc

Now, consider the following code:
-module(foo).
-compile([export_all,nowarn_export_all]).

loop_reverse_erl() ->
    L = lists:seq(1,1000000),
    loop_reverse_erl(L).

loop_reverse_erl(L) ->
    my_reverse(L,[]),
    loop_reverse_erl(L).

% vanilla reverse written in pure Erlang from efficiency_guide.erl
my_reverse([H|T], Acc) -> my_reverse(T, [H|Acc]);
my_reverse([], Acc) -> Acc.

When I launch the loop (foo:loop_reverse_erl().) from the shell, I see an activity on one of a dirty scheduler thread (with top -H -p <pid of beam.smp>)

The dirty scheduler doesn't do anything on a simple infinite loop like this
loop_reverse_erl(L) ->
    loop_reverse_erl(L).

I was expecting only native functions (BIFs / NIFs) are executed on the dirty schedulers.

Is it the expected behavior ? If yes, which conditions trigger the choice of the "dirty" or "normal" scheduler ?

OS: Linux RHEL 7
Erlang version: OTP/21 erts-10.0 (same on OTP/20)

Michael
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Dirty CPU scheduler and pure Erlang code

Michaël COQUARD
Hi Peti,

Thank you for your quick response, this is exactly what I was looking for. It was the garbage collector activity.

Michael

Le 19/09/2018 à 17:32, Peti Gömöri a écrit :
Hi Michael,

With the module `msacc` you can get more info about what the dirty scheduler is busy with. For example it can do garbage collection too.

On Wed, Sep 19, 2018 at 5:19 PM, Michaël COQUARD <[hidden email]> wrote:
Hi,

I try to understand how the processes are scheduled on the dirty schedulers.

As I understand, the dirty schedulers are meant to execute uninterruptible native code to avoid blocking the standard schedulers (and other Erlang processes) for a long time.

I noticed the majority of all memory allocations are scheduled on the dirty schedulers: mmap(), munmap() and mremap() calls from the mseg_alloc and sys_alloc

Now, consider the following code:
-module(foo).
-compile([export_all,nowarn_export_all]).

loop_reverse_erl() ->
    L = lists:seq(1,1000000),
    loop_reverse_erl(L).

loop_reverse_erl(L) ->
    my_reverse(L,[]),
    loop_reverse_erl(L).

% vanilla reverse written in pure Erlang from efficiency_guide.erl
my_reverse([H|T], Acc) -> my_reverse(T, [H|Acc]);
my_reverse([], Acc) -> Acc.

When I launch the loop (foo:loop_reverse_erl().) from the shell, I see an activity on one of a dirty scheduler thread (with top -H -p <pid of beam.smp>)

The dirty scheduler doesn't do anything on a simple infinite loop like this
loop_reverse_erl(L) ->
    loop_reverse_erl(L).

I was expecting only native functions (BIFs / NIFs) are executed on the dirty schedulers.

Is it the expected behavior ? If yes, which conditions trigger the choice of the "dirty" or "normal" scheduler ?

OS: Linux RHEL 7
Erlang version: OTP/21 erts-10.0 (same on OTP/20)

Michael
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Dirty CPU scheduler and pure Erlang code

Jesper Louis Andersen-2
In reply to this post by Michaël COQUARD
On Wed, Sep 19, 2018 at 5:27 PM Michaël COQUARD <[hidden email]> wrote:

I was expecting only native functions (BIFs / NIFs) are executed on the dirty schedulers.


Any work that is lengthy and not cooperative is better served with a task on the dirty scheduler. That way, we avoid blocking the scheduler thread which would mean we would stall processes. Long-running garbage collections are one such thing, so they can get backgrounded on the dirty scheduler. Once the GC is done, the process is moved back onto a "normal" scheduler.


--
J.

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions