I have been working on ways to improve performance of vector/matrix operations without having to resort to inline coding of the functions.
I have seen/written the various other libraries written in BMax but have been unhappy with the overall performance with pure max generated code.
Soo I started experimenting with implementing my own Objects in pure C code. It has also opened up the ability to utilize SSE extensions intrinsics exposed by GCC.
So I wrote a simple test BlitzMax Module in C that exposes the TVector3 object. This is a Max object but written in C. It uses some C compiler tricks to maximize performance. No StackFrames in particular when dealing with straight x87 FPU code. I pretty much lost this gain when I implmented the next part but the code is on par if not bit better than straight bmx code but not much.
The big gain comes from this..
There is also a global switch that when enabled the vector math is done via SSE extentions(havent figured out how I want to implement SSE detection).. On my Dual Core I am seeing speed up 30-33%. I am bit worried on inconsistent timing but is stable on my dual core machine.
(Win32 test)
http://smokenmirrors.com/Downloads/test.zip
BMX code so you can see whats going on. Just simple adds two vectors in loop and times them.
TVector which is coded in max with similar logic to a TVector3 which is coded in C.
Unlike many of the other libraries the approach of this library is that a Vector is not immutable. ie. Operations dont make new Vector Objects they Operate on the object. The reason for this approach vs. other is to avoid random invokation of garbage collection or memory allocations. It requires more thought and planing when using but it will create a much more consistent frame when dealing with large amounts of objects and extensive amounts of math since you need to be careful of allocations. This also applies for none GC languages when using heap based objects.
This sample is test for me to see some metrics on various machines before I spend much time coding out the more important usage of this which is to get SSE enabled Matrix functions as well as vector normalization.
This is coded currently to only work on PentiumIV(AMD?) or better due to switches and way I am currently building the module with but should eventually be able to be done so that it will automatically scale on X86 Processers as well as be cross compilable to PowerPC(does anyone use these)
Any test results/success or failure with machine specs would be appreciatd. Worst it should do is crash with illegal op code if SSE intructions are invoked on invalid platform.
Thanks
Doug
I have seen/written the various other libraries written in BMax but have been unhappy with the overall performance with pure max generated code.
Soo I started experimenting with implementing my own Objects in pure C code. It has also opened up the ability to utilize SSE extensions intrinsics exposed by GCC.
So I wrote a simple test BlitzMax Module in C that exposes the TVector3 object. This is a Max object but written in C. It uses some C compiler tricks to maximize performance. No StackFrames in particular when dealing with straight x87 FPU code. I pretty much lost this gain when I implmented the next part but the code is on par if not bit better than straight bmx code but not much.
The big gain comes from this..
There is also a global switch that when enabled the vector math is done via SSE extentions(havent figured out how I want to implement SSE detection).. On my Dual Core I am seeing speed up 30-33%. I am bit worried on inconsistent timing but is stable on my dual core machine.
(Win32 test)
http://smokenmirrors.com/Downloads/test.zip
BMX code so you can see whats going on. Just simple adds two vectors in loop and times them.
TVector which is coded in max with similar logic to a TVector3 which is coded in C.
Unlike many of the other libraries the approach of this library is that a Vector is not immutable. ie. Operations dont make new Vector Objects they Operate on the object. The reason for this approach vs. other is to avoid random invokation of garbage collection or memory allocations. It requires more thought and planing when using but it will create a much more consistent frame when dealing with large amounts of objects and extensive amounts of math since you need to be careful of allocations. This also applies for none GC languages when using heap based objects.
This sample is test for me to see some metrics on various machines before I spend much time coding out the more important usage of this which is to get SSE enabled Matrix functions as well as vector normalization.
This is coded currently to only work on PentiumIV(AMD?) or better due to switches and way I am currently building the module with but should eventually be able to be done so that it will automatically scale on X86 Processers as well as be cross compilable to PowerPC(does anyone use these)
Any test results/success or failure with machine specs would be appreciatd. Worst it should do is crash with illegal op code if SSE intructions are invoked on invalid platform.
Thanks
Doug
SuperStrict Framework brl.StandardIO Import dbs.vector 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 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 End Type Const MAXLOOP:Int= 200000000 Function TestCObject(sse:Int) EnableSSE(sse) Print "" If sse Print("C Vector SSE Enabled") Else Print("C Vector SSE Disabled") End If Local v1:TVector3 = New TVector3 v1.X=1 v1.Y=2 v1.Z=3 Local v2:TVector3 = New TVector3 v2.X=4 v2.Y=5 v2.Z=6 Local v3:TVector3 = New TVector3 StartTimer() For Local i:Int=0 To MAXLOOP v3.Add(v1,v2) Next Local secs:Double = StopTimer() Print "x="+v3.X+ " y="+v3.Y+" z="+v3.Z Print "C Code Time ="+secs +"ms" Print "Ops ="+(MaxLoop)/secs +" per ms" Print "" End Function 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 Print "Starting Tests" TestCObject(False) TestBMaxObject() TestCObject(True) Input("Press Enter to Exit")