[erlang-questions] Half word emulators and NIFs

Jon Watte <>
Thu Jun 30 05:08:55 CEST 2011


FWIW, The implementation of Erlang treats integers larger than 2^27 as
"bignums" which are separate from "regular integers." The reason it's not
2^31 or 2^32 is that Erlang uses a few bits for "tag bits," probably to
optimize the storage of these numbers within the garbage collected heap.

This also means that Erlang math arithmetic is not especially zippy compared
to most other languages, because the tag bits must generally be removed for
each operation.

Chances are that making an int64 *always* generates a bignum, whereas making
an int only makes a bignum if it's necessary. If the assumption is that
integers < 2^27 in magnitude are always little-ints, then it seems like the
behavior of making int64 is arguably broken for such numbers.

Sincerely,

jw



--
Americans might object: there is no way we would sacrifice our living
standards for the benefit of people in the rest of the world. Nevertheless,
whether we get there willingly or not, we shall soon have lower consumption
rates, because our present rates are unsustainable.



On Wed, Jun 29, 2011 at 3:11 PM, Paul Davis <>wrote:

> On Mon, Jun 27, 2011 at 6:03 AM, Sverker Eriksson
> <> wrote:
> > Have you tested with a debug built emulator. That may catch faulty NIF
> > behaviors earlier. Otherwise if a NIF builds broken terms on the process
> > heap it might not be discovered until later when those terms are matched
> or
> > maybe garbage collected.
> >
> > There is no difference to make NIF's for the halfword emulator. Just use
> the
> > NIF API as intended and don't cheat (make assumptions about
> > sizeof(ERL_NIF_TERM) for example).
> >
> > /Sverker, Erlang/OTP
> >
>
> I've reduced this to a failing test case in the NIF API [1].
>
> In the end it boils down to these two functions (notice one is int64,
> the other not):
>
> ERL_NIF_TERM
> run_test1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
> {
>    return enif_make_int64(env, 1);
> }
>
> ERL_NIF_TERM
> run_test2(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
> {
>    return enif_make_int(env, 1);
> }
>
> Test 1 returns a Value V where (V =:= 1) is false, but (V == 1) is
> true. The second function returns a value where both comparisons are
> true.
>
> Paolo also found that amusingly this bug disappears at 2^27 as shown by:
>
> ERL_NIF_TERM
> run_test3(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
> {
>    return enif_make_int64(env, 134217727);
> }
>
> ERL_NIF_TERM
> run_test4(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
> {
>    return enif_make_int64(env, 134217728);
> }
>
> run_test3 returns a value that can't be pattern matched against
> 134217727 but test 4 returns a value that can be matched against
> 134217728.
>
> Also, I built R14B03 on Ubuntu 10.04 with this configure:
>
> ./configure --enable-smp --enable-threads --enable-m64-build
> --without-javac --enable-halfword-emulator
>
> The processors are a pair of dual core Xeon's if that's important at all.
>
> [1] https://github.com/davisp/halfwordtest
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20110629/ef47133a/attachment.html>


More information about the erlang-questions mailing list