Computer Language Shootout - concurrency

Bjorn Gustavsson <>
Wed Dec 7 15:27:24 CET 2005


OK, I agree that it may not be immediately obvious from
reading the sources :-) , but addition is performed by a Beam
instruction (called "i_plus_jd" in beam_emu.c).
The BIF will be used if you apply erlang:'+'/2 (and
also used by match specifications).

The "i_plus_jd" instruction handles additions of small
integers directly. Only if one or both of the operands
are not small, or if the sum is not small, will the
erts_mixed_plus() function be called.

Knowing beforehand that both operands are integers would
not help because they may be bignums, so the type tests
would still be needed.

Introducing a new "is_small_integer/1" guard to eliminate
the type tests would probably not be worth it, because there
would be more instructions and you would probably lose more
time by instruction dispatching than you would win by
eliminating the type tests.

/Bjorn

"Ulf Wiger (AL/EAB)" <> writes:

> Oh, I should hasten to add that it was conjecture
> based on my reading of the code. I did not trace
> the benchmark code to see that erts_mixed_plus()
> in fact got called.
> 
> What I did was compile with the -S flag with and
> without is_integer/1 guards, and then run diff on
> the output. The only difference was the call to 
> the guard, but it didn't affect any of the other
> code.
> 
> In both cases, the following instruction was:
> 
>     {bif,'+',{f,0},[{x,1},{integer,1}],{x,0}}.
> 
> where the constant value is obviously tagged as 
> and integer.
> 
> In erl_bif.tab, the '+' operation seems to map
> to splus_2(), which turns around and calls 
> erts_mixed_plus(). I have failed to spot the 
> optimization that you speak of. That obviously
> isn't meant to imply that it isn't there - only
> that I was unable to find it.
> 
> /Uffe 
> 
> > -----Original Message-----
> > From:  
> > [mailto:] On Behalf Of Bjorn 
> > Gustavsson
> > Sent: den 7 december 2005 09:17
> > To: 
> > Subject: Re: Computer Language Shootout - concurrency
> > 
> > "Ulf Wiger (AL/EAB)" <> writes:
> > 
> > > I thought that, worst case, it wouldn't make a difference. As it is 
> > > now, the compiler inserts the is_integer/1 checks, but 
> > doesn't act on 
> > > the result. Eventually, the function splus_2 in erl_arith.c ends up 
> > > being called, and it turns around and calls 
> > erts_mixed_plus(), which 
> > > is so complex, I didn't even bother to understand it.
> > > It does handle all combinations of smallints, bignums and floats.
> > > 
> > 
> > This is strange.
> > 
> > Both Beam and hipe-native code have special cases for 
> > addition of "small integers" (signed integers that fit into 
> > 28 bits), so that erts_mixed_plus() does not get called.
> > 
> > Are you sure that the benchmark code itself causes the call 
> > erts_mixed_plus() (and not, for instance, the benchmarking 
> > framework)? Or could it be that the ackermann benchmark uses 
> > big numbers or floats?
> > 
> > /Bjorn
> > --
> > Björn Gustavsson, Erlang/OTP, Ericsson AB
> > 
> 

-- 
Björn Gustavsson, Erlang/OTP, Ericsson AB



More information about the erlang-questions mailing list