@Josh I did a simple test with just a BMX version using a the concept of Immutable Vectors as Mark/your lib vs Mutable Vector Objects my approach.
I was expecting poor performance based upon my understanding of architectural knowlege of Garbage Collector based language or heap based objects. I think you will be supprised at how bad it really is. I know I was as I waited and waited and waited for it to complete..
This is nothing more than simple add two vectors.
BMX Code
Now I know how much you are doing in regards with these Ops in your engine I suspect you might want to reconsider Immutable Vector/Matrix operations. The key here is you preallocate all your vector/matrix/quat and minimize in real time object creation.
As good as Marks GC is. It really is very fast. It still sucks alot of CPU cycles. This is no different that any object creation in any enviroment.
Now one way that might be able to speed it up is way that objects can have there own heaps instead of all sharing the same global GC heap. In C++/Object Pascal(Delphi)/D you can create custom allocators heaps per class. This way you can introduce allocation pools and increase the speed tremendouly. Still slower than preallocating but significantly faster non the less.
Myself coming from 8bit days am a speed freak, when it comes to heavly used routines such as math. Ideally I would like inlining. In that case even inline x87 code will beat overhead of function call to SSE optimized code.
My routines are pretty much best that you can do with function calls.
Thought you would find this interesting.
Doug
I was expecting poor performance based upon my understanding of architectural knowlege of Garbage Collector based language or heap based objects. I think you will be supprised at how bad it really is. I know I was as I waited and waited and waited for it to complete..
This is nothing more than simple add two vectors.
Building newtest Compiling:newtest.bmx flat assembler version 1.66 3 passes, 5367 bytes. Linking:newtest.exe Executing:newtest.exe Starting Tests BMX test Object x=5.00000000 y=7.00000000 z=9.00000000 BMX Time=1682.7540232068600ms Ops =118852.78373535293 per ms BMX test Immutable Object x=5.00000000 y=7.00000000 z=9.00000000 BMX Immutable Time=25544.810862833125ms Ops =7829.3787757494629 per ms Press Enter to Exit
BMX Code
SuperStrict Framework brl.StandardIO Extern "win32" Function QueryPerformanceFrequency(LARGE_INTEGER:Long Var) Function QueryPerformanceCounter(LARGE_INTEGER:Long Var) EndExtern Global freq : Long Global startcount : Long Global stopcount : Long QueryPerformanceFrequency(freq) Function StartTimer() QueryPerformanceCounter(startcount) End Function Function StopTimer:Double() QueryPerformanceCounter(stopcount) Return Double(stopcount-startcount)/(Double(freq)/1000) End Function Function Vector : TVector(x:Float,y:Float, z:Float) Local this : TVector = New TVector this.x = x this.y = y this.z = z Return this End Function Type TVector Field X:Float Field Y:Float Field Z:Float Method ToString:String() Return "x="+X+ " y="+Y+" z="+Z End Method Method Add:TVector(v1:TVector, v2:TVector) X=V1.X+V2.X Y=V1.Y+V2.Y Z=V1.Z+V2.Z Return Self End Method Method Plus:TVector( v:TVector) Return Vector ( x+v.x,y+v.y,z+v.z ) End Method End Type Const MAXLOOP:Int= 200000000 Function TestBMaxObject() Print "" Print("BMX test Object") Local vv1:TVector = New TVector vv1.X=1 vv1.Y=2 vv1.Z=3 Local vv2:TVector = New TVector vv2.X=4 vv2.Y=5 vv2.Z=6 Local vv3:TVector = New TVector StartTimer() For Local i:Int=0 To MAXLOOP vv3.Add(vv1,vv2) Next Local secs:Double = StopTimer() Print "x="+vv3.X+ " y="+vv3.Y+" z="+vv3.Z Print "BMX Time="+secs +"ms" Print "Ops ="+(MaxLoop)/secs +" per ms" Print "" End Function Function TestBMaxObjectImutable() Print "" Print("BMX test Immutable Object") Local vv1:TVector = New TVector vv1.X=1 vv1.Y=2 vv1.Z=3 Local vv2:TVector = New TVector vv2.X=4 vv2.Y=5 vv2.Z=6 Local vv3:TVector StartTimer() For Local i:Int=0 To MAXLOOP vv3=vv1.Plus(vv2) Next Local secs:Double = StopTimer() Print "x="+vv3.X+ " y="+vv3.Y+" z="+vv3.Z Print "BMX Immutable Time="+secs +"ms" Print "Ops ="+(MaxLoop)/secs +" per ms" Print "" End Function Print "Starting Tests" TestBMaxObject() TestBMaxObjectImutable Input("Press Enter to Exit")
Now I know how much you are doing in regards with these Ops in your engine I suspect you might want to reconsider Immutable Vector/Matrix operations. The key here is you preallocate all your vector/matrix/quat and minimize in real time object creation.
As good as Marks GC is. It really is very fast. It still sucks alot of CPU cycles. This is no different that any object creation in any enviroment.
Now one way that might be able to speed it up is way that objects can have there own heaps instead of all sharing the same global GC heap. In C++/Object Pascal(Delphi)/D you can create custom allocators heaps per class. This way you can introduce allocation pools and increase the speed tremendouly. Still slower than preallocating but significantly faster non the less.
Myself coming from 8bit days am a speed freak, when it comes to heavly used routines such as math. Ideally I would like inlining. In that case even inline x87 code will beat overhead of function call to SSE optimized code.
My routines are pretty much best that you can do with function calls.
Thought you would find this interesting.
Doug