[Vm-dev] Performance of primitiveFailFor: and use of primFailCode

David T. Lewis lewis at mail.msen.com
Tue May 24 03:42:23 UTC 2011


On Mon, May 23, 2011 at 07:30:09PM -0400, David T. Lewis wrote:
> On Mon, May 23, 2011 at 02:33:52PM -0700, Eliot Miranda wrote:
> >  
> > On Mon, May 23, 2011 at 2:08 PM, David T. Lewis <lewis at mail.msen.com> wrote:
> > >
> > >  Testing success status, original:
> > >        if (foo->successFlag) { ... }
> > >
> > >  Testing success status, new:
> > >        if (foo->primFailCode == 0) { ... }
> > >
> > >  Setting failure status, original:
> > >         foo->successFlag = 0;
> > >
> > >  Setting failure status, new:
> > >        if (foo->primFailCode == 0) {
> > >                foo->primFailCode = 1;
> > >        }
> > >
> > > So in each case the global struct is being used, both for successFlag
> > > and primFailCode. Sorry for the confusion. In any case, I'm still left
> > > scratching my head over the size of the performance difference.
> > >
> > 
> > One thought, where are successFlag and primFailCode in the struct?  Perhaps
> > the size of the offset needed to access them makes a difference?
> 
> In both cases they are the first element of the struct, so that
> cannot be it.
> 
> I think I had better circle back and redo my tests. Maybe I made
> a mistake somewhere.
>

No mistake, the performance problem was real.

Good news - I found the cause. Better news - this may be good for a
performance boost on StackVM and possibly Cog also.

The performance hit was due almost entirely to InterpreterPrimitives>>failed,
and perhaps a little bit to #successful and #success: also.

This issue with #failed is due to "^primFailCode ~= 0" which, for purposes
of C translation, can be recoded as "^primFailCode" with an override in
the simulator as "^primFailCode ~= 0". This produces a significant speed
improvement, at least as fast as for the original interpreter implementation
using successFlag.

I expect that the same change applied to StackInterpreter may give a similar
10% improvement (though I have not tried it). I don't know what to expect
with Cog, but it may give a boost there as well.

Changes attached, also included in VMMaker-dtl.237 on SqueakSource.

Dave

-------------- next part --------------
'From Squeak3.11alpha of 22 May 2011 [latest update: #11440] on 23 May 2011 at 11:32:52 pm'!
"Change Set:		InterpreterPlugins-primitiveFailFor-speedup-dtl
Date:			23 May 2011
Author:			David T. Lewis

Recode #failed, #successful, and #success: for performance when translated to C. The main performance benefit comes from #failed. Simulator subclasses must reimplement these for execution in Smalltalk. Do not use #cCode:inSmalltalk: as this requires knowledge of the interpreter global structure, hence the use of overrides in interpreter subclasses."!


!InterpreterPrimitives methodsFor: 'primitive support' stamp: 'dtl 5/23/2011 21:22'!
failed
	"Answer true if primFailCode is not zero. This implementation is only for
	translation to C, and should not be modified without testing performance.
	Simulator subclasses must override this method as primFailCode ~= 0.
	Do not use #cCode:inSmalltalk: as this requires knowledge of the interpreter
	global structure."
	<api>
	^primFailCode "override in simulator as primFailCode ~= 0"! !

!InterpreterPrimitives methodsFor: 'primitive support' stamp: 'dtl 5/23/2011 22:09'!
success: successBoolean
	"Set the state of the primitive failure code/success flag, iff successBoolean
	 is false. If primFailCode is non-zero a primitive has failed.  If primFailCode
	 is greater than one then its value indicates the reason for failure."

	"Use returnTypeC: #sqInt because that's the way it is defined in sq.h.
	 Use no explicit return so that Slang doesn't fail an inlin ingtype-check when
	 a primitive with return type void uses ^self success: false to exit."
	<returnTypeC: #sqInt>
	<inline: true>
	successBoolean ifFalse:
		["Don't overwrite an error code that has already been set."
		 self successful ifTrue:
			[primFailCode := 1]]! !

!InterpreterPrimitives methodsFor: 'primitive support' stamp: 'dtl 5/23/2011 21:34'!
successful
	"Answer the state of the primitive failure code/success flag.  If
	 primFailCode is non-zero a primitive has failed.  If primFailCode
	 is greater than one then its value indicates the reason for failure.
	This implementation is only for translation to C, and should not be
	modified without testing performance. Simulator subclasses must
	override this method as primFailCode == 0. Do not use #cCode:inSmalltalk:
	as this requires knowledge of the interpreter global structure."
	<inline: true>
	^primFailCode not "override this in simulator as primFailCode == 0"! !


!InterpreterProxy methodsFor: 'other' stamp: 'dtl 5/23/2011 21:36'!
failed
	^primFailCode ~= 0! !

!InterpreterProxy methodsFor: 'other' stamp: 'dtl 5/23/2011 21:44'!
success: aBoolean
	self failed ifTrue:[^self].
	aBoolean ifFalse: [
		primFailCode := 1.
		(self confirm:'A primitive is failing -- Stop simulation?') ifTrue:[self halt]]
! !

!InterpreterProxy methodsFor: 'other' stamp: 'dtl 5/23/2011 22:22'!
successful
	^primFailCode == 0! !



More information about the Vm-dev mailing list