FFI is sloooow ; ) [ Was: Re: [squeak-dev] Re: Alien vs. FFI benchmarks (Re: Trying to load ALienOpenGL into 4.1 alpha...) ]

Bert Freudenberg bert at freudenbergs.de
Fri Apr 9 08:49:00 UTC 2010


On 09.04.2010, at 10:44, Igor Stasenko wrote:
> 
> Okay, here's my results with ffi callout code generated on the fly:
> 
> NativeCodeTests new benchWinCall
> 
> #(752 288 205)
> 
> It benching a famous glGetError() function :)
> 
> benchWinCall
> 	| time1 time2 time3 |
> 	
> 	
> 	time1 := [ 1000000 timesRepeat: [ self ffiglError ] ] timeToRun.
> 	time2 := [ 1000000 timesRepeat: [ self nbglError ] ] timeToRun.
> 	time3 := [ 1000000 timesRepeat: [  ] ] timeToRun.
> 	
> 	^ { time1. time2. time3 }
> 
> ((752-205) /(288-205) ) asFloat
> 6.59  times faster!!
> 
> The original ffi method is following:
> 
> ffiglError
> 	<apicall: long 'glGetError' () module: 'opengl32.dll'>
> 	self primitiveFailed
> 
> And then, i replacing it with following:
> 
> nbglError
> 	<primitive: 'primitiveNativeCall' module: 'NativeBoostPlugin'>
> "primitiveExternalCall"
> 	self primitiveFailed
> 
> the native code, which is attaching to this method is written manually ;)
> Here it is:
> 
> genWinCall
> 	| addr asm fn |
> 	self winCall.
> 	
> 	" ( (NativeCodeTests methodDict at: #winCall) literalAt: 1) getHandle "
> 	addr := ((self class methodDict at: #ffiglError) literalAt: 1) getHandle.
> 	addr := addr asInteger.
> 	
> 	asm := AJx86AsmBuilder x86.
> 
> 	fn := NBInterpreterProxyGen functions at: #signed32BitIntegerFor: .
> 	
> 	asm
> 		push: EBP;
> 		mov:  ESP->EBP;
> 		
> 		"call external function"
> 		mov: (asm imm: addr) -> EAX;
> 		call: EAX;
> 		push: EAX; "push return value"
> 
> 		"push function to call"
> 		mov: (asm mem: EBP) + 12 to: EAX;
> 		mov: (asm mem: EAX) + (fn index * 4) to: EAX;
> 		push: EAX;
> 		
> 		" call gate function"
> 		mov: (asm mem: EBP) + 8 to: EAX;
> 		call: EAX;
> 
> 		" clear the stack "
> 		leave;
> 		ret.
> 		
> 	self install: asm bytes into: (self class methodDict at: #nbglError)
> 	
> Of course, all this asm hackish stuff should be replaced by callout
> autogenerator,
> which should do everything by just taking a ffi pragma (<apicall: long
> 'glGetError' () module: 'opengl32.dll'> )
> and nothing else :)
> 
> I will post additional benchmarks for functions which use some arguments later.
> 
> -- 
> Best regards,
> Igor Stasenko AKA sig.
> 

Way cool :)

- Bert -





More information about the Squeak-dev mailing list