Efficient code...

Everything else that doesn't fall into one of the other PB categories.
Escobar
User
User
Posts: 17
Joined: Tue Aug 05, 2003 5:54 pm

Efficient code...

Post by Escobar »

Hello everyone!

I have a question about which one of the following two (2) instructions are executed faster by the processor: multiplication (*) or making a comparsion ( >, < or = ) between two values (doesn't matter if it's an integer, float or string or whatever)? Is it faster to make a comparsion between two values than making a multiplication?
Another question: When should you consider to have a function/procedure written "inline" instead of making it a separated code that you make a call for (with a pointer or something)? I'm thinking in terms of speed vs. code size.

Thank you in advance
GPI
PureBasic Expert
PureBasic Expert
Posts: 1394
Joined: Fri Apr 25, 2003 6:41 pm

Post by GPI »

A Multiplikation is slow, very slow (ok, in some cases *2, *4, *8,*16... it is fast). So when you can prevent multiplikations, do it!
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Post by tinman »

This code confirms GPI's post (unless I've done something wrong). Certainly in PB anyway. If you're looking to a lower level then you probably also need to take into consider things such as the effect of losing a pipeline due to a branch, branch prediction (instruction caches), speed of executing an instruction, and whether the condition codes are updated as part of a multiplication. This will all be processor specific, with the worst case being pipeline length (meaning you could lose different numbers of instructions) depending on processor.

Code: Select all

start_time.l=GetTickCount_()
For i.l=0 To 1000000000
    If 0>1
    EndIf
Next
end_time.l=GetTickCount_()-start
time.f = end_time - start_time : time = time / 1000
MessageRequester("Took", StrF(time), #PB_MessageRequester_OK)

start_time.l=GetTickCount_()
For i.l=0 To 1000000000
    If 0<1
    EndIf
Next
end_time.l=GetTickCount_()-start
time.f = end_time - start_time : time = time / 1000
MessageRequester("Took", StrF(time), #PB_MessageRequester_OK)

start_time.l=GetTickCount_()
For i.l=0 To 1000000000
    f.l = f * -1
Next
end_time.l=GetTickCount_()-start
time.f = end_time - start_time : time = time / 1000
MessageRequester("Took", StrF(time), #PB_MessageRequester_OK)
Under Windows, the first loop compiles to the following. This shows that the generated code performs an unconditional branch/jump for the if/endif part, which may not actually represent real life if you are comparing against something.

Code: Select all

; For i.l=0 To 1000000000
  MOV    dword [v_i],0
_For1:
  MOV    eax,1000000000
  CMP    eax,dword [v_i]
  JL    _Next2
; If 0>1
  JMP     _EndIf4
; EndIf
_EndIf4:
; Next
_NextContinue2:
  INC    dword [v_i]
  JMP   _For1
_Next2:
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
thefool
Always Here
Always Here
Posts: 5875
Joined: Sat Aug 30, 2003 5:58 pm
Location: Denmark

Post by thefool »

get the asm - optimizing help file.
u just launch it from pb gui then.
there is a lot there.
all on all its a great read.
and what i have tried so far from it works with PB.
Also it has a great topic about Reducing code size. I know it only
has trics that saves a few bytes, but if u have a really large app and want
to optimize the size, its good to read. Also optimizing speed and such.
but thats just what i suggest
Escobar
User
User
Posts: 17
Joined: Tue Aug 05, 2003 5:54 pm

Post by Escobar »

Thank you guys for the answers...

I suspected that multiplications are slower than comparing two values but I wasn't sure. I don't know assembler well but I understod your code 'tinman' :wink: thanks! And thank you 'thefool' for your suggestions I will look into it :D

The reason I'm asking this is that I'm trying to figure out a collision detection routine and I want to get rid of the squareroot calc's and even all the multiplications by substitute it with a comparsion routine/algorithm. Something like Axis Aligned Boundary Boxes.
Doobrey
Enthusiast
Enthusiast
Posts: 218
Joined: Sat Apr 26, 2003 4:47 am
Location: Dullsville..population: me
Contact:

Post by Doobrey »

Escobar wrote: I suspected that multiplications are slower than comparing two values but I wasn't sure.
A compare just subtracts one number from the other, then checks the status of the condition flags.
If it`s equal, the zero flag is set, or the carry flag is set if the second number is smaller than the first.

As for how CPU`s do multiplications?? I`ll pass on that, I`ve only just about grasped 68K asm, let alone understood the inner workings!
As a very bad guess, the simplest way is just to do a looping add, but then you`ve no guarantee of the CPU returning within a set number of cycles...
freedimension
Enthusiast
Enthusiast
Posts: 613
Joined: Tue May 06, 2003 2:50 pm
Location: Germany
Contact:

Post by freedimension »

Doobrey wrote: As for how CPU`s do multiplications?? I`ll pass on that, I`ve only just about grasped 68K asm, let alone understood the inner workings!
As a very bad guess, the simplest way is just to do a looping add, but then you`ve no guarantee of the CPU returning within a set number of cycles...
No, believe it or not, it's more like you would do with pen and paper ;-)
Post Reply