Some questions

bryce at kampjes.demon.co.uk bryce at kampjes.demon.co.uk
Sat May 5 14:35:48 UTC 2007


Guillermo Adrián Molina writes:
 > > In Exupery the SmallInteger addtion sequence is
 > >    bitTest arg1
 > >    jumpIfSet failureBlock
 > >    bitTest arg2
 > >    jumpIfSet failureBlock
 > >    clearTagBit arg1
 > >    add arg1 arg2
 > >    jumpOverflow failureBlock
 > >
 > > The failure case is a full message send.
 > >
 > The problem with the above code is that you have 3 branches.
 > That is why I need jump tables, there are cases where cmov really dosn't help

There is only 3 branches and I'm hoping that they will never be
taken so they should be easy to predict. That said the branches do
use branch predictor resources which could cause other branches not
to be predicted as well.

 > Before I started using exupery, I called special methods in C that
 > implemented faster code. Every special method (and primitives) returned 1
 > in case of an error, and if success, returned the result object.
 > One of this special methods was +. This is part of the code:
 > 
 > if(areIntegers(rcvr,arg)) {
 > 	int result;
 > 	asm(	"movl $1,%%edx\n\t"
 > 		"movl %[rcvr],%[result]\n\t"
 > 		"addl %[arg],%[result]\n\t"
 > 		"cmovol %%edx,%[result]"
 > 		: [result] "=r" (result)
 > 		: [rcvr] "r" (rcvr), [arg] "r" (arg)
 > 		: "edx" );
 > 	return result;
 > }
 > 
 > with this code, I've got up to 10% faster code in + intensive tests.

Do you have conditionals inside areIntegers and to check if the result
is 1 indicating an error?

 > > There are code fragments where cmov whould be helpful. Converting
 > > to a boolean comes to mind. The part of "a > b" where you're loading
 > > either true or false into the result register.
 > >
 > 
 > Yes, I implemented that with exupery (code for less "<"):
 > 
 > self addExpression:  (MedMov
 > 	from: (self literal: false)
 > 	to: answer	).
 > trueReg := machine createTemporaryRegister.
 > self addExpression:  (MedMov
 > 	from: (self literal: true)
 > 	to: trueReg	).
 > self addExpression:  (MedComparision
 > 	operator: #cmp
 > 	arg1: arg1
 > 	arg2: arg2).
 > self addExpression:  (MedCMov
 > 	type: #cmovl
 > 	from: trueReg
 > 	to: answer).
 > 
 > This gave me an impressive improvement (up to 40-50%), when I implemented
 > all the smallint comparissons in this way. Because, as you know, we dont
 > need to detag before compare.

Exupery removes many of the boolean conversion sequences.

	"a < b ifTrue: [x]"

First gets translated into:

      (booleanToControlFlow (controlFlowToBoolean (a < b)))

Then Exupery removes the booleanToControlFlow controlFlowToBoolean
sequence. The booleanToControlFlow sequence is moved to the failure
case where either a or b are not SmallIntegers.

So I'm not sure if speeding up the general case will help Exupery
as I'm not sure how often it's called.

Bryce


More information about the Exupery mailing list