[Vm-dev] Integer comparition primitive failures on Cog

Igor Stasenko siguctua at gmail.com
Mon May 2 10:48:06 UTC 2011


Hmm.. that's really strange, because as far as i can see,
the code there are the same:

(primitive: 3)

Interpreter>>primitiveLessThan
	| integerReceiver integerArgument |
	integerArgument := self popInteger.
	integerReceiver := self popInteger.
	self checkBooleanResult: integerReceiver < integerArgument

InterpreterPrimitives>>primitiveLessThan
	| integerReceiver integerArgument |
	integerArgument := self popInteger.
	integerReceiver := self popInteger.
	self checkBooleanResult: integerReceiver < integerArgument

and #popInteger also same (it fails if value on stack are not smallinteger).
So, in Squeak VM comparison primitive also fails,
which should lead to evaluating failure code.

One way how to speed this up, is when primitive fails, do not use super-sends,
but instead use double dispatch, i.e. instead :

SmallInteger >> < aNumber
	"Primitive. Compare the receiver with the argument and answer with
	true if the receiver is less than the argument. Otherwise answer false.
	Fail if the argument is not a SmallInteger. Essential. No Lookup. See
	Object documentation whatIsAPrimitive."

	<primitive: 3>
	^super < aNumber

do something like:


SmallInteger >> < aNumber
	"Primitive. Compare the receiver with the argument and answer with
	true if the receiver is less than the argument. Otherwise answer false.
	Fail if the argument is not a SmallInteger. Essential. No Lookup. See
	Object documentation whatIsAPrimitive."

	<primitive: 3>
       ^ aNumber isGreaterOrEqualToSmallInteger: self

and then effectively,
Float>> isGreaterOrEqualToSmallInteger: aSmallInteger

could be implemented as a primitive which takes a smallinteger as
argument and does comparison without need to convert integer
to Float first.

Also, a primitives for floats accepting a smallintegers as arguments,
so by rewriting:


SmallInteger >> < aNumber
	"Primitive. Compare the receiver with the argument and answer with
	true if the receiver is less than the argument. Otherwise answer false.
	Fail if the argument is not a SmallInteger. Essential. No Lookup. See
	Object documentation whatIsAPrimitive."

	<primitive: 3>
       ^ aNumber >=  self


 [1 to: 2000000 do: [:i |
    i < 2354.234. ] timeToRun

before:

8223

after:
20

so... 421 times faster :)

On 2 May 2011 12:12, Henrik Sperre Johansen
<henrik.s.johansen at veloxit.no> wrote:
>
> As per my comment on the recent Morphic performance
> graphs,(http://blog.openinworld.com/2011/03/morphic-flavour-performance/#comment-59)
> on a Cog VM these primitives fail with a Float parameter, which leads to a
> huge performance hit when comparing Ints to Floats by doing silly things in
> the fallback code.
>
> Cog:
> [1 to: 2000000 do: [:i |
>    i < 2354.234.
>    i <= 2354.234.
>    i >= 2354.234.
>     i > 2354.234.]] timeToRun 26594
>
> Trunk:
> [1 to: 2000000 do: [:i |
>    i < 2354.234.
>    i <= 2354.234.
>    i >= 2354.234.
>     i > 2354.234.]] timeToRun 229
>
> Should this be changed in the VM, or is the difference for pure int/int
> comparition large enough that we should instead change
> Float>>adaptToInteger: andCompare:
> to use the corresponding comparitions with Float as receiver, which does
> work?
> That's still slower than trunk in my image, but quite a bit better, above
> test takes about 1s.
>
> Cheers,
> Henry
>



-- 
Best regards,
Igor Stasenko AKA sig.


More information about the Vm-dev mailing list