Davies wrote:
As mentioned before, unlike most users, I am only interested in floating point calculations. Unfortunately there don't appear to be any definitive benchmark comparisons between the different flavours.
One thing that seems clear is that the fastest performance for floating point calculations is achieved using the FPU instruction set. Does anyone know whether PureBasic automatically uses the FPU instruction set for such calculations or would I have to stuggle and do it myself in ASM?
If I was to write most of the simulation is straight BASIC with just the key calculations in inline ASM, can anyone please tell me is the procedure to add inline ASM the same for each flavour and which would be easiest to use?
Here you have some of my ASM optimized codes useful for physic simulations. These are vectoring calculations in 2D. The functions are written in ASM and maximum optimized for speed. If you want to get still more speed then just simply put the Procedure content in the place where it is called, replacing the call to procedure.
The samples have a PROVE section to watch what it perform:
Code: Select all
;Assembler function to find the projected vector of a given vector onto another one.
;NOTE: This function doesn't use any trigonometric function, but geometric calculation.
; Author: Psychophanta
; Date: 24 Dic 2003
Procedure Project_Vector()
;-Project_Vector ASM Function:
!fld dword[v_v+20];<-Horizontal coord of vector to project onto.
!fst st1;<-Make a copy of it in st1.
!fld st0;<-Make a copy of it in st1.
!fmul st1,st0;<-Horizontal coord^2 in st1.
!fmul dword[v_v];<- st0 = Horizontal coord of vector * Horizontal coord of vector to project onto.
!fld dword[v_v+24];<-Vertical coord of vector to project onto.
!fst st4;<-Make a copy of it in st4.
!fld st0;<-Make a copy of it in st1.
!fmul st0,st0;<-Vertical coord^2 to st0.
!faddp st3,st0;<-Vertical coord in st0. (Horizontal coord of vector * Horizontal coord of vector to project onto) in st1. (Horizontal coord^2+Vertical coord^2) in st2.
!fmul dword[v_v+4];<- st0 = Vertical coord of vector * Vertical coord of vector to project onto.
!faddp st1,st0;<-(Vertical coord of vector * Vertical coord of vector to project onto) + (Horizontal coord of vector * Horizontal coord of vector to project onto) now in st0. (Horizontal coord^2+Vertical coord^2) in st1.
!fdivrp st1,st0;<-Constant result to multiply by vector to project onto, to get the wanted vector.
!fmul st1,st0;<-Horizontal coord result in st1.
!fmul st0,st2;<-Vertical coord result in st0.
!fstp dword[v_v+4]
!fst dword[v_v]
;*End Project_Vector ASM Function
EndProcedure
Structure vector
c1.f;<-horizontal coord
c2.f;<-vertical coord
Length.f;<-length(modulo)
Angle.f;<- angle
LateralForce.f;<-Side force factor. It is the tangent of the angle to rotate.
;A 1 here means an inclination deviation of 45 degrees,
;from 0 to +-1 implicates a deviation of 0 to +-45 degrees,
;from +-1 to +-infinite implicates a deviation of +-45 to +-90 degrees.
p1.f;<-horizontal coord of vector to project onto
p2.f;<-vertical coord of vector to project onto
EndStructure
;-PROVE IT:
;-INITS:
bitplanes.b=32:RX.w=1024:RY.w=768:#PI=3.14159265
If InitMouse()=0 Or InitSprite()=0 Or InitKeyboard()=0
MessageRequester("Error","Can't open DirectX",0)
End
EndIf
While OpenScreen(RX.w,RY.w,bitplanes.b,"Balls")=0
If bitplanes.b>16:bitplanes.b-8
ElseIf RY.w>600:RX.w=800:RY.w=600
ElseIf RY.w>480:RX.w=640:RY.w=480
ElseIf RY.w>400:RX.w=640:RY.w=400
ElseIf RY.w>240:RX.w=320:RY.w=240
ElseIf RY.w>200:RX.w=320:RY.w=200
Else:MessageRequester("VGA limitation","Can't open Screen!",0):End
EndIf
Wend
;-MAIN:
CX.w=RX.w/2:CY.w=RY.w/2
c1.f=100:c2.f=200;<-initial vector
v.vector\p1=300:v.vector\p2=30;<-vector to project onto.
Repeat
ExamineKeyboard()
ExamineMouse()
If MouseButton(1)=0 And MouseButton(2)=0:c1.f+MouseDeltaX():c2.f+MouseDeltaY()
ElseIf MouseButton(2):CX.w+MouseDeltaX():CY.w+MouseDeltaY()
ElseIf MouseButton(1):v.vector\p1+MouseDeltaX():v.vector\p2+MouseDeltaY()
EndIf
v.vector\c1=c1.f:v.vector\c2=c2.f
modp.f=Sqr(v.vector\p1*v.vector\p1+v.vector\p2*v.vector\p2)
modc.f=Sqr(v.vector\c1*v.vector\c1+v.vector\c2*v.vector\c2)
ClearScreen(0,0,0)
StartDrawing(ScreenOutput())
Line(CX.w,CY.w,v.vector\c1,v.vector\c2,$CCCCCC)
Line(CX.w+v.vector\c1,CY.w+v.vector\c2,-v.vector\c1*10/modc.f+v.vector\c2*10/modc.f,-v.vector\c2*10/modc.f-v.vector\c1*10/modc.f,$CCCCCC)
Line(CX.w+v.vector\c1,CY.w+v.vector\c2,-v.vector\c1*10/modc.f-v.vector\c2*10/modc.f,-v.vector\c2*10/modc.f+v.vector\c1*10/modc.f,$CCCCCC)
Line(CX.w,CY.w,v.vector\p1,v.vector\p2,$AADDCC)
Line(CX.w+v.vector\p1,CY.w+v.vector\p2,-v.vector\p1*10/modp.f+v.vector\p2*10/modp.f,-v.vector\p2*10/modp.f-v.vector\p1*10/modp.f,$AADDCC)
Line(CX.w+v.vector\p1,CY.w+v.vector\p2,-v.vector\p1*10/modp.f-v.vector\p2*10/modp.f,-v.vector\p2*10/modp.f+v.vector\p1*10/modp.f,$AADDCC)
Project_Vector()
modc.f=Sqr(v.vector\c1*v.vector\c1+v.vector\c2*v.vector\c2)
Line(CX.w,CY.w,v.vector\c1,v.vector\c2,$11FFFF)
Line(CX.w+v.vector\c1,CY.w+v.vector\c2,-v.vector\c1*10/modc.f+v.vector\c2*10/modc.f,-v.vector\c2*10/modc.f-v.vector\c1*10/modc.f,$11FFFF)
Line(CX.w+v.vector\c1,CY.w+v.vector\c2,-v.vector\c1*10/modc.f-v.vector\c2*10/modc.f,-v.vector\c2*10/modc.f+v.vector\c1*10/modc.f,$11FFFF)
StopDrawing()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
CloseScreen()
Code: Select all
;Assembler function to find the projected vector of a given vector onto another one.
;NOTE: This function doesn't use any trigonometric function, but geometric calculation.
; Author: Psychophanta
; Date: 24 Dic 2003
Procedure Ortogonal_Project_Vector()
;-Ortogonal_Project_Vector ASM Function:
!fld dword[v_v+20];<-Horizontal coord of vector to project onto.
!fst st1;<-Make a copy of it in st1.
!fld st0;<-Make a copy of it in st1.
!fmul st1,st0;<-Horizontal coord^2 in st1.
!fmul dword[v_v+4];<- st0 = Vertical coord of vector * Horizontal coord of vector to project onto.
!fld dword[v_v+24];<-Vertical coord of vector to project onto.
!fst st4;<-Make a copy of it in st4.
!fld st0;<-Make a copy of it in st1.
!fmul st0,st0;<-Vertical coord^2 to st0.
!faddp st3,st0;<-Vertical coord in st0. (Horizontal coord of vector * Horizontal coord of vector to project onto) in st1. (Horizontal coord^2+Vertical coord^2) in st2.
!fmul dword[v_v];<- st0 = Horizontal coord of vector * Vertical coord of vector to project onto.
!fsubp st1,st0;<-(Vertical coord of vector * Horizontal coord of vector to project onto) - (Horizontal coord of vector * Vertical coord of vector to project onto) now in st0. (Horizontal coord^2+Vertical coord^2) in st1.
!fdivrp st1,st0;<-Constant result to multiply by vector to project onto, to get the wanted vector.
!fmul st1,st0;<-Horizontal coord result in st1.
!fmul st0,st2;<-Vertical coord result in st0.
!fchs
!fstp dword[v_v]
!;<-moving previous fchs here would result in a opposed projected vector
!fst dword[v_v+4]
;*End Ortogonal_Project_Vector ASM Function
EndProcedure
Structure vector
c1.f;<-horizontal coord
c2.f;<-vertical coord
Length.f;<-length(modulo)
Angle.f;<- angle
LateralForce.f;<-Side force factor. It is the tangent of the angle to rotate.
;A 1 here means an inclination deviation of 45 degrees,
;from 0 to +-1 implicates a deviation of 0 to +-45 degrees,
;from +-1 to +-infinite implicates a deviation of +-45 to +-90 degrees.
p1.f;<-horizontal coord of vector to project onto
p2.f;<-vertical coord of vector to project onto
EndStructure
;-PROVE IT:
;-INITS:
bitplanes.b=32:RX.w=1024:RY.w=768:#PI=3.14159265
If InitMouse()=0 Or InitSprite()=0 Or InitKeyboard()=0
MessageRequester("Error","Can't open DirectX",0)
End
EndIf
While OpenScreen(RX.w,RY.w,bitplanes.b,"Balls")=0
If bitplanes.b>16:bitplanes.b-8
ElseIf RY.w>600:RX.w=800:RY.w=600
ElseIf RY.w>480:RX.w=640:RY.w=480
ElseIf RY.w>400:RX.w=640:RY.w=400
ElseIf RY.w>240:RX.w=320:RY.w=240
ElseIf RY.w>200:RX.w=320:RY.w=200
Else:MessageRequester("VGA limitation","Can't open Screen!",0):End
EndIf
Wend
;-MAIN:
CX.w=RX.w/2:CY.w=RY.w/2
c1.f=100:c2.f=200;<-initial vector
v.vector\p1=300:v.vector\p2=30;<-vector to project onto.
Repeat
ExamineKeyboard()
ExamineMouse()
If MouseButton(1)=0 And MouseButton(2)=0:c1.f+MouseDeltaX():c2.f+MouseDeltaY()
ElseIf MouseButton(2):CX.w+MouseDeltaX():CY.w+MouseDeltaY()
ElseIf MouseButton(1):v.vector\p1+MouseDeltaX():v.vector\p2+MouseDeltaY()
EndIf
v.vector\c1=c1.f:v.vector\c2=c2.f
modp.f=Sqr(v.vector\p1*v.vector\p1+v.vector\p2*v.vector\p2)
modc.f=Sqr(v.vector\c1*v.vector\c1+v.vector\c2*v.vector\c2)
ClearScreen(0,0,0)
StartDrawing(ScreenOutput())
Locate(0,0):DrawText("Lateral Amount: "+StrF(v.vector\c2*v.vector\p1-v.vector\c1*v.vector\p2))
Line(CX.w,CY.w,v.vector\c1,v.vector\c2,$CCCCCC)
Line(CX.w+v.vector\c1,CY.w+v.vector\c2,-v.vector\c1*10/modc.f+v.vector\c2*10/modc.f,-v.vector\c2*10/modc.f-v.vector\c1*10/modc.f,$CCCCCC)
Line(CX.w+v.vector\c1,CY.w+v.vector\c2,-v.vector\c1*10/modc.f-v.vector\c2*10/modc.f,-v.vector\c2*10/modc.f+v.vector\c1*10/modc.f,$CCCCCC)
Line(CX.w,CY.w,v.vector\p1,v.vector\p2,$AADDCC)
Line(CX.w+v.vector\p1,CY.w+v.vector\p2,-v.vector\p1*10/modp.f+v.vector\p2*10/modp.f,-v.vector\p2*10/modp.f-v.vector\p1*10/modp.f,$AADDCC)
Line(CX.w+v.vector\p1,CY.w+v.vector\p2,-v.vector\p1*10/modp.f-v.vector\p2*10/modp.f,-v.vector\p2*10/modp.f+v.vector\p1*10/modp.f,$AADDCC)
Ortogonal_Project_Vector()
modc.f=Sqr(v.vector\c1*v.vector\c1+v.vector\c2*v.vector\c2)
Line(CX.w,CY.w,v.vector\c1,v.vector\c2,$11FFFF)
Line(CX.w+v.vector\c1,CY.w+v.vector\c2,-v.vector\c1*10/modc.f+v.vector\c2*10/modc.f,-v.vector\c2*10/modc.f-v.vector\c1*10/modc.f,$11FFFF)
Line(CX.w+v.vector\c1,CY.w+v.vector\c2,-v.vector\c1*10/modc.f-v.vector\c2*10/modc.f,-v.vector\c2*10/modc.f+v.vector\c1*10/modc.f,$11FFFF)
StopDrawing()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
CloseScreen()
Code: Select all
;Assembler function to rotate a given vector due to a perpendicular attraction or repulsion force.
;Resulting vector has SAME LENGTH and modified inclination.
;The lateral force is given as a factor which:
; -from 0 to +-1 implicates a deviation of 0 to +-45 degrees of the given vector,
; -from +-1 to +-infinite implicates a deviation of +-45 to +-90 degrees of the given vector.
;So then, note that the given factor is the tangent of the angle to rotate.
;NOTE: This function doesn't use any trigonometric function, but geometric calculation.
; Author: Psychophanta
; Date: 24 Dic 2003
Procedure Rotate_Vector_by_Side_Force()
;-Rotate_Vector_by_Side_Force ASM Function:
!fld dword[v_v+16];<-SideForceFactor
!fld st0;<-Make a copy of it in st1
!fmul st0,st0;<-SideForceFactor^2
!fld1;<-push a 1 in st0
!faddp st1,st0;<-Now (SideForceFactor^2 + 1) in st0. SideForceFactor in st1.
!fsqrt ;<-Now Sqr(SideForceFactor^2 + 1) in st0. SideForceFactor in st1.
!fld dword[v_v+4];<-Vertical coord in st0. Sqr(SideForceFactor^2 + 1) in st1. SideForceFactor in st2.
!fld dword[v_v];<-horizontal coord in st0. Vertical coord in st1. Sqr(SideForceFactor^2 + 1) in st2. SideForceFactor in st3.
!fld st1;<-y in st0 and in st2. x coord in st1. Sqr(SideForceFactor^2 + 1) in st3. SideForceFactor in st4.
!fmul st0,st4;<-(y * SideForceFactor) in st0.
!fsubr st0,st1;<-(x - y * SideForceFactor) in st0.
!fdiv st0,st3;<-That's the new x coord (x - y * SideForceFactor)/Sqr(SideForceFactor^2 + 1) in st0.
!fstp dword[v_v];<-store it. Now x coord in st0. y in st1. Sqr(SideForceFactor^2 + 1) in st2. SideForceFactor in st3.
!fmulp st3,st0;<-(x * SideForceFactor) in st2. y in st0. Sqr(SideForceFactor^2 + 1) in st1.
!faddp st2,st0;<-(y + x * SideForceFactor) in st1. Sqr(SideForceFactor^2 + 1) in st0.
!fdivp st1,st0;<-the wanted value y coord (y + x * SideForceFactor)/Sqr(SideForceFactor^2 + 1) is now in st0.
!fstp dword[v_v+4];<-store it.
;*End Rotate_Vector_by_Side_Force ASM Function
EndProcedure
Structure vector
c1.f;<-horizontal coord
c2.f;<-vertical coord
Length.f;<-length(modulo)
Angle.f;<- angle
LateralForce.f;<-Side force factor. It is the tangent of the angle to rotate.
;A 1 here means an inclination deviation of 45 degrees,
;from 0 to +-1 implicates a deviation of 0 to +-45 degrees,
;from +-1 to +-infinite implicates a deviation of +-45 to +-90 degrees.
EndStructure
;-PROVE IT:
;-INITS:
bitplanes.b=32:RX.w=1024:RY.w=768:#PI=3.14159265
If InitMouse()=0 Or InitSprite()=0 Or InitKeyboard()=0
MessageRequester("Error","Can't open DirectX",0)
End
EndIf
While OpenScreen(RX.w,RY.w,bitplanes.b,"Balls")=0
If bitplanes.b>16:bitplanes.b-8
ElseIf RY.w>600:RX.w=800:RY.w=600
ElseIf RY.w>480:RX.w=640:RY.w=480
ElseIf RY.w>400:RX.w=640:RY.w=400
ElseIf RY.w>240:RX.w=320:RY.w=240
ElseIf RY.w>200:RX.w=320:RY.w=200
Else:MessageRequester("VGA limitation","Can't open Screen!",0):End
EndIf
Wend
;-MAIN:
CX.w=RX.w/2:CY.w=RY.w/2
v.vector\c1=-43;<-vector x coordenate
v.vector\c2=27;<-vector y coordenate
v.vector\LateralForce=-1/50;<-Side force factor
Repeat
ExamineKeyboard()
ExamineMouse()
If MouseButton(1)=0 And MouseButton(2)=0:v.vector\LateralForce+MouseDeltaX()/1000
ElseIf MouseButton(2):CX.w+MouseDeltaX():CY.w+MouseDeltaY()
ElseIf MouseButton(1):v.vector\c1+MouseDeltaX():v.vector\c2+MouseDeltaY()
EndIf
ClearScreen(0,0,0)
StartDrawing(ScreenOutput())
Locate(0,0):DrawText(StrF(v.vector\LateralForce)+" units")
Rotate_Vector_by_Side_Force()
modc.f=Sqr(v.vector\c1*v.vector\c1+v.vector\c2*v.vector\c2)
Line(CX.w,CY.w,v.vector\c1,v.vector\c2,$11FFFF)
Line(CX.w+v.vector\c1,CY.w+v.vector\c2,-v.vector\c1*10/modc.f+v.vector\c2*10/modc.f,-v.vector\c2*10/modc.f-v.vector\c1*10/modc.f,$11FFFF)
Line(CX.w+v.vector\c1,CY.w+v.vector\c2,-v.vector\c1*10/modc.f-v.vector\c2*10/modc.f,-v.vector\c2*10/modc.f+v.vector\c1*10/modc.f,$11FFFF)
StopDrawing()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
CloseScreen()
Code: Select all
;Assembler function to modulate a given vector, this is, to transform a given vector to another
;with a given length (modulo):
; Author: Psychophanta
; Date: 22 Dic 2003
Procedure Modulate_Vector()
;-Get_Modulated_Vector ASM Function: <-To obtain vector (v.vector\c1,v.vector\c2) with a length of v.vector\length.
!fld dword[v_v+8];<-the New Length wanted for the vector
!fld dword[v_v];<-horizontal coord
!fld st0;<-horizontal coord in st1 too
!fmul st0,st0;<- x^2
!fld dword[v_v+4];<-vertical coord
!fld st0;<- in st1 too
!fmul st0,st0;<- y^2
!fadd st0,st2;<- x^2+y^2 now in st0. NewLength in st4
!fsqrt;<-Sqr(x^2+y^2) now in st0
!fdivp st4,st0;<-NewLength/Sqr(x^2+y^2) is the value to multiply each old vector component to get the new ones.
!fstp st1;<-mov st0 to st1 and pop, this is flush st1
!fmul st0,st2;<-new vertical coord now in st0
!fstp dword[v_v+4];<-new vertical coord
!fmulp st1,st0
!fstp dword[v_v];<-new horizontal coord
;*End Get_Modulated_Vector ASM Function
EndProcedure
Structure vector
c1.f;<-horizontal coord
c2.f;<-vertical coord
length.f;<-length (modulo)
EndStructure
;-PROVE IT:
;-INITS:
bitplanes.b=32:RX.w=1024:RY.w=768:#PI=3.14159265
If InitMouse()=0 Or InitSprite()=0 Or InitKeyboard()=0
MessageRequester("Error","Can't open DirectX",0)
End
EndIf
While OpenScreen(RX.w,RY.w,bitplanes.b,"Balls")=0
If bitplanes.b>16:bitplanes.b-8
ElseIf RY.w>600:RX.w=800:RY.w=600
ElseIf RY.w>480:RX.w=640:RY.w=480
ElseIf RY.w>400:RX.w=640:RY.w=400
ElseIf RY.w>240:RX.w=320:RY.w=240
ElseIf RY.w>200:RX.w=320:RY.w=200
Else:MessageRequester("VGA limitation","Can't open Screen!",0):End
EndIf
Wend
;-MAIN:
CX.w=RX.w/2:CY.w=RY.w/2
c1.f=-43;<-vector x coordenate
c2.f=27;<-vector y coordenate
v.vector\length=30;<-wanted length
Repeat
ExamineKeyboard()
ExamineMouse()
If MouseButton(1)=0 And MouseButton(2)=0:v.vector\length+MouseDeltaX()
ElseIf MouseButton(2):CX.w+MouseDeltaX():CY.w+MouseDeltaY()
ElseIf MouseButton(1):c1.f+MouseDeltaX():c2.f+MouseDeltaY()
EndIf
v.vector\c1=c1.f:v.vector\c2=c2.f
ClearScreen(0,0,0)
StartDrawing(ScreenOutput())
Locate(0,0):DrawText(StrF(v.vector\length)+" units")
modc.f=Sqr(v.vector\c1*v.vector\c1+v.vector\c2*v.vector\c2)
Line(CX.w,CY.w,v.vector\c1,v.vector\c2,$CCCCCC)
Line(CX.w+v.vector\c1,CY.w+v.vector\c2,-v.vector\c1*10/modc.f+v.vector\c2*10/modc.f,-v.vector\c2*10/modc.f-v.vector\c1*10/modc.f,$CCCCCC)
Line(CX.w+v.vector\c1,CY.w+v.vector\c2,-v.vector\c1*10/modc.f-v.vector\c2*10/modc.f,-v.vector\c2*10/modc.f+v.vector\c1*10/modc.f,$CCCCCC)
Modulate_Vector()
modc.f=Sqr(v.vector\c1*v.vector\c1+v.vector\c2*v.vector\c2)
Line(CX.w,CY.w,v.vector\c1,v.vector\c2,$11FFFF)
Line(CX.w+v.vector\c1,CY.w+v.vector\c2,-v.vector\c1*10/modc.f+v.vector\c2*10/modc.f,-v.vector\c2*10/modc.f-v.vector\c1*10/modc.f,$11FFFF)
Line(CX.w+v.vector\c1,CY.w+v.vector\c2,-v.vector\c1*10/modc.f-v.vector\c2*10/modc.f,-v.vector\c2*10/modc.f+v.vector\c1*10/modc.f,$11FFFF)
StopDrawing()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
CloseScreen()
If you want more, just ask for it.
I hope these is usefel for you to know how.
