Packages

Various BEAM benchmarks in one place

Current section

Files

Jump to
beam_benchmarks src ehb ehb.erl
Raw

src/ehb/ehb.erl

%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2009. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
%%
%% %CopyrightEnd%
%%%-------------------------------------------------------------------
%%% File : ehb.erl
%%% Author : Rickard Green
%%% Description : An Erlang HackBench version
%%%
%%% Created : 24 Aug 2009 by Rickard Green
%%%-------------------------------------------------------------------
-module(ehb).
-export([bench_args/2, run/3]).
-define(ACK, 100).
-define(DATA, {a,b,c,d,e,f,g,h,i,j,k,l}). %% 104 bytes on a 64-bit machine
-define(GSIZE, 20).
bench_args(Version, Conf) ->
{_,Cores} = lists:keyfind(number_of_cores, 1, Conf),
[F1, F2] = case Version of
short -> [1, 4];
intermediate -> [2,8];
long -> [8, 8]
end,
[[N,M] || N <- [F1 * Cores], M <- [F2 * Cores]].
run([N,M|_], _, _) ->
Master = self(),
Gs = lists:map(fun (_) -> group(Master, M) end, lists:seq(1, N)),
lists:foreach(fun (G) -> receive {G, ready} -> ok end end, Gs),
lists:foreach(fun (G) -> G ! {Master, go} end, Gs),
lists:foreach(fun (G) -> receive {G, done} -> ok end end, Gs),
ok.
group(Master, Loop) ->
spawn_link(fun () ->
GMaster = self(),
Rs = lists:map(fun (_) ->
spawn_link(fun () -> receiver(GMaster, ?GSIZE) end)
end, lists:seq(1, ?GSIZE)),
Ss = lists:map(fun (_) ->
spawn_link(fun () ->
receive {GMaster, go} -> sender(Rs,Loop) end
end)
end, lists:seq(1, ?GSIZE)),
Master ! {self(), ready},
receive {Master, go} -> ok end,
lists:foreach(fun (S) -> S ! {GMaster, go} end, Ss),
lists:foreach(fun (R) -> receive {R, done} -> ok end end, Rs),
Master ! {self(), done}
end).
sender(Rs, 0) ->
lists:foreach(fun (R) -> R ! done end, Rs);
sender(Rs, Loop) when Loop > ?ACK ->
sender_ack(Rs, ?ACK),
sender(Rs, Loop - ?ACK);
sender(Rs, Loop) ->
lists:foreach(fun (R) -> R ! ?DATA end, Rs),
sender(Rs, Loop-1).
sender_ack(Rs, 2) ->
lists:foreach(fun (R) ->
R ! ?DATA,
R ! {self(), are_you_keeping_up}
end, Rs),
lists:foreach(fun (R) ->
receive {R, i_am_keeping_up} -> ok end,
R ! ?DATA
end, Rs),
ok;
sender_ack(Rs, N) ->
lists:foreach(fun (R) -> R ! ?DATA end, Rs),
sender_ack(Rs, N-1).
receiver(GMaster, SendersLeft) ->
receive
done ->
case SendersLeft of
1 -> GMaster ! {self(), done};
_ -> receiver(GMaster, SendersLeft - 1)
end;
Msg ->
case Msg of
{From, are_you_keeping_up} -> From ! {self(), i_am_keeping_up};
_ -> ok
end,
receiver(GMaster, SendersLeft)
end.