Bug in HiPE on x86-64?

Stefan Axelsson L (LN/EAB) <>
Tue Jun 20 14:28:43 CEST 2006


Hi, I'm seeing different behaviour depending on whether a module is
compiled with HiPE and without, when I make a call with a function
argument. It works when I wrap the function in an anonymous function
though. Is this a feature or a bug? I've read the documentation and
while there are a few differences noted, nothing really jumps out at me
that would explain this (I'm a relative newbie to Erlang, so that's not
to say isn't in there of course).

Below are a few test cases that provoke the deviation. In the first case
the evaluation succeeds and in the second I get an error message.
Removing the -smp switch makes no difference. As mentioned, invoking the
test as: "merge_sort:test_sort(1000000, 1, fun(N,Xs)->
merge_sort:merge_sort(N,Xs) end)/1000000." works, i.e. Produces the
expected results.

This is on an AMD Opteron x86-64. The code and details are included
below.

------------------------------------------------------------------------
-------------
:~/Erlang> erl -smp
Erlang (BEAM) emulator version 5.5 [source] [64-bit] [smp:2]
[async-threads:0] [hipe]

Eshell V5.5  (abort with ^G)
1> c(merge_sort).
{ok,merge_sort}
2> merge_sort:test_sort(1000000, 1, fun
merge_sort:merge_sort/2)/1000000.
2.69710
------------------------------------------------------------------------
-------------
:~/Erlang> erl -smp
Erlang (BEAM) emulator version 5.5 [source] [64-bit] [smp:2]
[async-threads:0] [hipe]

Eshell V5.5  (abort with ^G)
1> c(merge_sort,native).
{ok,merge_sort}
2> merge_sort:test_sort(1000000, 1, fun
merge_sort:merge_sort/2)/1000000.
** exited: {{badfun,#Fun<merge_sort.merge_sort.2>},[]} **
3>
=ERROR REPORT==== 20-Jun-2006::11:10:20 ===
Error in process <0.32.0> with exit value:
{{badfun,#Fun<merge_sort.merge_sort.2>},[]}
------------------------------------------------------------------------
--------------
:~/Erlang> erl -smp
Erlang (BEAM) emulator version 5.5 [source] [64-bit] [smp:2]
[async-threads:0] [hipe]

Eshell V5.5  (abort with ^G)
1> c(merge_sort,native).
{ok,merge_sort}
2> merge_sort:test_sort(1000000, 1, fun(N,Xs)->
merge_sort:merge_sort(N,Xs) end)/1000000.
2.65750
3>
------------------------------------------------------------------------
--------------
Same results in all cases without -smp.

:~/Erlang> uname -a
Linux genset01 2.6.5-7.191-smp #1 SMP Tue Jun 28 14:58:56 UTC 2005
x86_64 x86_64 x86_64 GNU/Linux
------------------------------------------------------------------------
--------------
-module(merge_sort).
-export([merge_sort/2, sorter/2, randlist/2, test_sort/3]).

% Multi threaded merge sort. Spawn as many processes as there are
% processors (n). Let each sort 1/n of the input. Merge the results.

% Split a list into a lists of N lists, could do with a pair of
% reverse to fix the problem that the big lists come at the end.
split_list(0, Xs) ->
    Xs;
split_list(N, Xs) ->
    {Hs, Ts} = lists:split(trunc(length(Xs)/N), Xs),
    [Hs | split_list(N-1, Ts) ].

% Do N receive messages and return list of all results regardless of
% what message was
do_receive(N) ->
    do_receive(N, []).

do_receive(0, A) ->
    A;
do_receive(N, A) ->
    receive
        X ->
            do_receive(N-1, [X|A])
    end.

% S sorting process, that sorts a list and sends the result back
sorter(Receiver, Xs) ->
%    io:format("~w sorting length ~p ~n", [self(), length(Xs)]), % Brag
about parallelism
    Receiver ! lists:sort(Xs).

% Spawn N processes, let them sort and merge the results
% The merge ought to be tree like with the merging in steps in parallel?
merge_sort(N, Xs) ->
    Me = self(),
    Lists = split_list(N, Xs),                  % One chunk per process
    lists:foreach(fun(Zs) -> spawn(merge_sort, sorter, [Me, Zs]) end,
Lists),
    Sorts = do_receive(N),                      % Collect results
%    lists:foldr(fun(X,Y) -> lists:merge(X,Y) end, [], Sorts). % Merge
    lists:merge(Sorts).                         % Merge

% Randlist, generate a random list of length N with ints between 1-K
randlist(N, K) ->
    lists:map(fun(_) -> random:uniform(K) end, lists:duplicate(N, 0)).

% Test the sort, generate a random list of length M and sort with N
processes,
% return the number of microseconds
% Ex: merge_sort:test_sort(1000000, 2, fun
merge_sort:merge_sort/2)/1000000.
test_sort(M, N, The_sort) ->
    Tests = randlist(M, 400000000),
    {StMs, StS, StUS} = now(),                  % St(art) M(ega)sec,
sec, usecs
    The_sort(N, Tests),
    {EnMs, EnS, EnUS} = now(),                  % E(nd) M(ega)sec etc.
    (EnUS-StUS) + (EnS-StS)*1000000 + (EnMs-StMs)*1000000*1000000.
------------------------------------------------------------------------
--------------

Best Regards,
--
Stefan Axelsson PhD  (ERVSTAX)  PDU PCN Syst. Mgmt.  tel: 031-747 3963
(mobile/work)



More information about the erlang-questions mailing list