Fastcall speed results, did I goof up?

Everything else that doesn't fall into one of the other PB categories.
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Fastcall speed results, did I goof up?

Post by Dare2 »

The following code is a simple test of results (tested without debugger) on calls using std procedure call and fastcall via different addresses.

The results are not as expected (but actually suit me!) and I am wondering if my test logic is bad.

Any comments?

Code: Select all

Structure myCallDef
  adr.l
  ad.l[10]
EndStructure

jmp.myCallDef

Procedure aa(va,vb)
  c=va-vb
  ProcedureReturn va-vb
EndProcedure

; expectations:
; 1. scalar var fastest as addr resolved outside loop. Actually worst.
; 2. @addr as resolved inside loop but no structure resolution
; 3. addr in structure.
; 4. addr in structure, in 'array' of items. - Is consistently best!
; 5. standard procedure call.

jmp\ad[0]=@aa()
jmp\adr=@aa()
k=@aa()


t=getTickCount_()
i=0

; uncomment line to test.
; Is this test logic flawed?

While getTickCount_()<t+500
  ;  i+CallFunctionFast(jmp\ad[0],2,1)         ; #1 thought @4 (10% up on std)
  ;  i+CallFunctionFast(jmp\adr,2,1)           ; #2 thought @3
  ;  i+aa(2,1)                                 ; #3 thought @5
  ;  i+CallFunctionFast(@aa(),2,1)             ; #4 thought @2 (5% down on std)
  ;  i+CallFunctionFast(k,2,1)                 ; #5 thought @1
Wend
MessageRequester("RESULTS","Times done ="+Str(i),0)
@}--`--,-- A rose by any other name ..
filperj
User
User
Posts: 77
Joined: Tue Sep 16, 2003 8:53 pm
Location: Nevers(France)

Post by filperj »

:?:
As expected, standard call i+aa(2,1) is the fastest: executed 73 million times while 2 seconds, all the others was under 70 millions.
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

Hi, thanks.

When I increased the loop time, std call did become slightly faster than the rest.

So I guess my sample was pathetic. :)

Now I need to see if using an array of dynamic calls is slower than having a large number of IF tests, eg If flg=1 : procedureA() : ElseIf flg=2 : procedureB() : etc versus CallFunctionFast(jmp\addr[flg]

I'm betting on it - maybe not - I would have lost the house on my last bet. :)

Thanks again.
@}--`--,-- A rose by any other name ..
filperj
User
User
Posts: 77
Joined: Tue Sep 16, 2003 8:53 pm
Location: Nevers(France)

Post by filperj »

I think the "CallFunctionFast(jmp\addr[flg])" method should be faster, as each test has to read value, compare, jump to next test ...
Well,it's my humble opinion, I did not test :roll:
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

You're right.

And I was betting on it so I won back the house. :)

EDIT:

Hmmm.

Wording in my previous post suggests I was betting on the if/else list. So in a real game I guess my opponent could claim I lost. I lose two houses! :(
@}--`--,-- A rose by any other name ..
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

Post by NoahPhense »

Maybe I'm just being silly.. but I've never used CFF like that, because
when I initially ran speed tests, I saw almost no speed difference between
@aa(1,2) or standard calling..

The only place I really taste CFF's benefits, is when using a dll or lib.
By pregrabbing the memory address of the function and storing it to
AddIt with IsFunction() ..

Code: Select all

#MyDLL = 1 ; library number

Global AddIt.l  ; global for CFF

; // initLib // ----------------------------------------------------- //
Procedure initLib()
  If OpenLibrary(#MyDLL, "sample.dll")
    AddIt = IsFunction(#MyDLL, "function1")
  Else
    MessageRequester("Missing DLL", "The Primary DLL is missing -- cannot continue.", #PB_MessageRequester_Ok | #MB_IconExclamation | #MB_SystemModal)
    End
  EndIf
EndProcedure

; // AddThese // ---------------------------------------------------- //
Procedure.l AddThese(a.l, b.l)
  ProcedureReturn CallFunctionFast(AddIt, a, b)
EndProcedure

; // CloseLib // ---------------------------------------------------- //
Procedure CloseLib() 
  CloseLibrary(#MyDLL)
EndProcedure 




initLib()

result.s = Str(AddThese(1,2))

MessageRequester("Result", result, #PB_MessageRequester_Ok | #MB_IconInformation | #MB_SystemModal)

CloseLib()

End
- np
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

Heya,

I intend to use this in my mutlimedia-type app. It contains a 'program' with commands handling midi, images, flash, etc etc etc. This prog is stored in a memory bank.

As a command pointer moves across the bank I currently do the following:

Code: Select all

If *curPos\cmd & $FF = #_cmdWhatEver
  procWhatEver()
ElseIf *curPos\cmd & $FF = #_cmdWhatEverElse
  procWhatEverElse()

etc
There are 256 commands, and some of them are extended (have another byte) commands.

I am looking at doing something like this inside a structure array of longs:

Code: Select all

jmp\proc[#_cmdWhatEver]      = @procWhatEver()
jmp\proc[#_cmdWhatEverElse] = @procWhatEverElse()
etc, then

Code: Select all

CallFunctionFast(*jmp\proc[*curPos\cmd & $FF])
And in the extended command procs doing a second jump.

Which, I hope, makes my life easier. :)
@}--`--,-- A rose by any other name ..
Post Reply