The Computer Language
Benchmarks Game

chameneos-redux Erlang HiPE program

source code

% The Computer Language Benchmarks Game
% http://benchmarksgame.alioth.debian.org/
%%% contributed by Christian von Roques
%%% modified by Jiri Isa

%% Each chameneos is its own process.
%% A chameneos sends {self(), Color} to the broker to request a
%% meeting with another chameneos.
%% The broker replies with {Pid, Color} of the partner met or 'stop'
%% whereupon the chameneos prints the Meetings and Selfmeetings it had
%% and replies with the number of Meetings for the broker to sum.

-module(chameneosredux).
-export([main/1]).

-import(lists, [foreach/2]).

spell(0) -> " zero";
spell(N) -> spell(N, []).

spell(0, L) -> L;
spell(N, L) -> spell(N div 10, [element(N rem 10 + 1, {" zero", " one", " two", " three", " four", " five", " six", " seven", " eight", " nine"}) | L]).


complement(C, C) -> C;
complement(blue, red) -> yellow;
complement(blue, yellow) -> red;
complement(red, blue) -> yellow;
complement(red, yellow) -> blue;
complement(yellow, blue) -> red;
complement(yellow, red) -> blue.


show_complements() ->
    [ io:fwrite("~p + ~p -> ~p~n", [A, B, complement(A, B)]) ||
        A <- [blue, red, yellow],
        B <- [blue, red, yellow]].


print_header(L) ->
    io:fwrite("~n"),
    foreach(fun(C) -> io:fwrite(" ~p", [C]) end, L),
    io:fwrite("~n").


run(L, N) ->
    print_header(L),
    Broker = self(),
    foreach(fun(Color) -> spawn(fun() -> chameneos(Broker, Color, 0, 0) end) end, L),
    broker(N),
    cleanup(length(L), 0).


chameneos(Broker, Color, Meetings, MetSelf) ->
    Broker ! { self(), Color },
    receive
        {OPid, OColor} ->
            chameneos(Broker, complement(Color, OColor), Meetings+1,
                      if OPid == self() -> MetSelf+1; true -> MetSelf end);
        stop ->
            io:fwrite("~w~s\n", [Meetings, spell(MetSelf)]),
            Broker ! Meetings
    end.


broker(0) -> nil;
broker(N) ->
    receive
        C1 = {Pid1, _} -> nil
    end,
    receive
        C2 = {Pid2, _} ->
            Pid1 ! C2,
            Pid2 ! C1,
            broker(N-1)
    end.

cleanup(0, M) -> io:fwrite("~s~n", [spell(M)]);
cleanup(N, M) ->
    receive
        {Pid, _Color} ->
            Pid ! stop,
            cleanup(N, M);
        Meetings ->
            cleanup(N-1, M+Meetings)
    end.


main([Arg]) ->
    N = list_to_integer(Arg),
    show_complements(),
    run([blue, red, yellow], N),
    run([blue, red, yellow, red, yellow, blue, red, yellow, red, blue], N),
    io:fwrite("~n"),
    halt(0).

    

notes, command-line, and program output

NOTES:
32-bit Ubuntu one core
Erlang/OTP 19 [erts-8.0] [source] [async-threads:10] [hipe] [kernel-poll:false]



Fri, 24 Jun 2016 01:01:14 GMT

MAKE:
mv chameneosredux.hipe chameneosredux.erl
/usr/local/src/otp_src_19.0_nosmp/bin/erlc +native +"{hipe, [o3]}"  chameneosredux.erl
rm chameneosredux.erl
0.69s to complete and log all make actions

COMMAND LINE:
/usr/local/src/otp_src_19.0_nosmp/bin/erl -smp disable -noshell -run  chameneosredux main 6000000

PROGRAM OUTPUT:
blue + blue -> blue
blue + red -> yellow
blue + yellow -> red
red + blue -> yellow
red + red -> red
red + yellow -> blue
yellow + blue -> red
yellow + red -> blue
yellow + yellow -> yellow

 blue red yellow
4000000 zero
4000000 zero
4000000 zero
 one two zero zero zero zero zero zero

 blue red yellow red yellow blue red yellow red blue
1200000 zero
1200000 zero
1200000 zero
1200000 zero
1200000 zero
1200000 zero
1200000 zero
1200000 zero
1200000 zero
1200000 zero
 one two zero zero zero zero zero zero