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

Igor Stasenko siguctua at gmail.com
Fri Apr 9 08:44:34 UTC 2010


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.



More information about the Squeak-dev mailing list