Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / A little Speed Test for Various Loops + the ASM that DarkBasic Converts them To for Reference..

Author
Message
Sedit
User Offline
Joined: 3rd Sep 2017
Location: Ghetto of NJ
Posted: 24th Nov 2017 06:44
I decided to make and run a small Benchmark test to check the speed of various loops in DarkBasic but my program crashed because I have been having serious memory issues more then likely unrelated to this program. It turned out to be sort of a blessing and I thought this was kind of cool, in C:\USERS\ APPdata\TEMP I found the Darkbasic pro Crash report and since this program was loaded up at the time of the crash It gave me the ASM that Darkbasic Generates which I for one being an OLD ASM programmer thought was pretty cool.

Thought I would share for anyone interested,

It even has the line numbers so you can learn what commands are translated to what.



On my system FOR_NEXT was a clear winner at around 60 milliseconds to run 10 million cycles


Everything else was around 450ms - 500ms
I would be very interested in hearing how everyone elses computers performed to see if mine is alot slower or pretty standard.



THE DBPro CODE:





THE GENERATED ASM CODE:
Sphere sphere = new Sphere(0.5f);
InsanelyRedundantJava insanelyredundantjava = new InsanelyRedundantJava(Redundancy1, Redundancy2);
Ortu
DBPro Master
10
Years of Service
User Offline
Joined: 21st Nov 2007
Location: Austin, TX
Posted: 24th Nov 2017 20:34
yeah, for next is definitely fastest, particularly for iterating arrays try to avoid the 'next array index' method and use for/next with array count instead.
http://games.joshkirklin.com/sulium

A single player RPG featuring a branching, player driven storyline of meaningful choices and multiple endings alongside challenging active combat and intelligent AI.
Sedit
User Offline
Joined: 3rd Sep 2017
Location: Ghetto of NJ
Posted: 24th Nov 2017 23:15
Agreed, I was going to use the INSERT ARRAY commands because I thought they might be quicker since I could get it to act like a Stack and I wouldn't have to check if a Creature ID was already in use in my array but instead it proved INSANELY slow. It was much faster for me to cycle through and test every element in a 10000 byte array then it was for me to just add to the front or back of it using the Various Array commands.

Trying to think of some more comparative test to perform of similar functions because I wish to get a good idea as to the fastest means of doing things in darkbasic since Speed is King in alot of the type of stuff I like to do.

I just found the commands for writing to the backbuffer directly so I might try doing a test between direct screen drawing through the memory compared to using the DOT and POINT functions. These are kind of important to my program anyway so would be good to know.


ORTU!!! LOOK, the end of the some of the variables used by I believe DBPro are marked with the _ symbol, I wonder if this could have something to do with why I am getting errors attempting to use _ in my comments.
I wonder if I can force this temp ASM file to stay so that I can see what exactly is going on when that REM error shows up.
Sphere sphere = new Sphere(0.5f);
InsanelyRedundantJava insanelyredundantjava = new InsanelyRedundantJava(Redundancy1, Redundancy2);
Ortu
DBPro Master
10
Years of Service
User Offline
Joined: 21st Nov 2007
Location: Austin, TX
Posted: 25th Nov 2017 00:21
Seems likely.

I use _ in variable names all the time, but never more than 1 consecutive, and Chris Tate mentioned the issue specifically regarding comments.
http://games.joshkirklin.com/sulium

A single player RPG featuring a branching, player driven storyline of meaningful choices and multiple endings alongside challenging active combat and intelligent AI.
Sedit
User Offline
Joined: 3rd Sep 2017
Location: Ghetto of NJ
Posted: 25th Nov 2017 01:19
I noticed it had to do with _ at the end of comments as well, Im just wondering if perhaps its attempting to view the _ as a variable nullifying the fact that its really a comment. It looks like Comments from the BASIC code are included in the output ASM. Im attempting to break a normal File so I can obtain the ASM output of any program so I can get a better Idea whats going on in the compiler. I know DB is open source but this just seems easier to read then attempting to wade through thousands of lines of C++ code.

It just struck me as odd when reading it. I assumed _ was messing it up due to a parse error but Im starting to wonder if it might be due to something deeper.
Sphere sphere = new Sphere(0.5f);
InsanelyRedundantJava insanelyredundantjava = new InsanelyRedundantJava(Redundancy1, Redundancy2);
Sedit
User Offline
Joined: 3rd Sep 2017
Location: Ghetto of NJ
Posted: 29th Nov 2017 07:08
I decided to write the same program in C++ because I started to think about the program Im working on now and since I am no longer using 3D Im not sure why I am not writing it in C++

I wanted a quick benchmark to see if C++ increase in speed was going to be worth the slower development time I am going to get into. Here is the Code I used, Its damn near a word for word copy of the Above BASIC code just translated to C++ to test the loop speeds.



The results really really surprised me... I mean I expected DBPro to be slower but what I did not expect was how much slower. Not so much the FOR_NEXT loop, That was slower then C++ but not the way the others are.

FOR _NEXT --- 31ms
While ---- 31M/s
Do-While(equ to REPEAT-WHILE) 47
GOTO label loop 47ms....


So why is DBPro getting such poor results on the other loops I just don't understand. The FOR-NEXT was around half as slow but the Variance is between 30-45ms or so meaning in reality Darkbasic was only Slightly Slower the C++ on the FOR NEXT LOOP and Honestly more stable as far as the amount of time is concerned... But why are the others over 10x almost 20 x in some cases slower?

Is that really the Mathematical side of it? Is it the fact that I am adding X = X+1 in these loops that's making that big of a difference? That would make my savings insane if I switched to C++. I know this is a DBPro forum and all and almost blasphemy to say it but I don't think I can continue this project on Darkbasic,


Don't get me wrong I love Darkbasic for what it is. Its so great at prototyping and graphical stuff I can get stuff out of my head and on the screen pretty much the speed I can think of it which is impossible in C++. I have to spend as much time setting up libraries and deciding what I need to use then it takes to write half the program in Darkbasic

But if that is really the difference in Arithmetics... How can I possibly go on writing a Calculation based Simulation.
Sphere sphere = new Sphere(0.5f);
InsanelyRedundantJava insanelyredundantjava = new InsanelyRedundantJava(Redundancy1, Redundancy2);
Bored of the Rings
13
Years of Service
User Offline
Joined: 25th Feb 2005
Location: Middle Earth
Posted: 29th Nov 2017 08:39 Edited at: 10th Dec 2017 10:37
@Sedit-thanks for sharing.

[edited]
Professional Programmer, languages: SAS, C++, SQL, PL-SQL, DBPro, Purebasic, JavaScript, others
Mage
11
Years of Service
User Offline
Joined: 3rd Feb 2007
Location: Canada
Posted: 29th Nov 2017 09:28
I hope you see this reply I am curious about some of the things you mentioned.

Bored of the Rings wrote: "...MEMBLOCKS in general are slow I tend to use Matrix1UTIL BANKS..."

I have not explored the Matrix1 Util Plugin extensively. How much faster is this? What are the differences? Are there any limitations?

Bored of the Rings wrote: "...my .X exporter from DBO format to X (binary to aSCII)..."

This is interesting since I have long considered converting Milkshape 3D models to X Format or DBO for Dark Basic Pro to be a pain in the ass. I find that all too often models come out with wrongly adjusted joints, missing joints or other inconsistencies. Right now in order to Export from Milkshape3D I need to save, Import into Fragmotion (a program that requires typing the lords prayer, you read that right, once a week to even launch), play around with a few settings, and export to X Format. A one shot converter from MS3D to DBO would be quite nice. Do you have any resource that might be helpful for this? A layout of the DBO file format for example? I remember a long time ago seeing a resource discussed that.
Bored of the Rings
13
Years of Service
User Offline
Joined: 25th Feb 2005
Location: Middle Earth
Posted: 29th Nov 2017 09:58 Edited at: 10th Dec 2017 10:37
[edited]
Professional Programmer, languages: SAS, C++, SQL, PL-SQL, DBPro, Purebasic, JavaScript, others

Attachments

Login to view attachments
zero32
1
Years of Service
User Offline
Joined: 28th Jul 2016
Location:
Posted: 12th Dec 2017 07:06 Edited at: 12th Dec 2017 07:46
You compare print : sync with cout. Of course printing to a directx window is slower that printing to a console window. The matrix1 Plugin can open a console window and print to it.

edit: oh seems like you didn't use the print command inside the loop. sorry.
"It is only slightly easier than changing all sugar in a cake into stevia after it has already been baked" -Bisqwit
Kevin Picone
15
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 12th Dec 2017 13:32

From memory, the Dbpro compiler defaults to building loops that include 'message pumps' so the user can break out of infinite loops. There's a toggle somewhere to turn it off.

PlayBASIC To HTML5/WEB - Convert PlayBASIC To Machine Code
Sedit
User Offline
Joined: 3rd Sep 2017
Location: Ghetto of NJ
Posted: 12th Dec 2017 17:27
That would be great to know,
Anyone here have additional info on any such switch because I can handle breaking out of loops on my own that's not an issue

That would explain why Do, While and repeat fared so poorly over something like a next loop that knows its going to have an end somewhere.
Sphere sphere = new Sphere(0.5f);
InsanelyRedundantJava insanelyredundantjava = new InsanelyRedundantJava(Redundancy1, Redundancy2);
Rudolpho
12
Years of Service
User Offline
Joined: 28th Dec 2005
Location: Sweden
Posted: 12th Dec 2017 18:41
Well, one thing you have in your pasted assembly dump yourself - for each DBPro instruction an error check is injected into the generated code:

So the above stores the current line number, checks some global error variable and jumps to the error handler if the error value was not zero. This is just four instructions, but if you have this injected into each cycle of a loop that merely increments a variable, or indeed does nothing at all, it will add considerable extra runtime.
Interestingly this happens in the for loop as well as the others, so the message pump work that Kevin points out seems a likely culprit. It is unfortunate then that this is not included in the asm dump; who know what else may be injected but not logged?

Another thing, did you turn all optimizations off when measuring your C++ performance?
If you did not any reasonably intelligent compiler would optimize

into
Sedit
User Offline
Joined: 3rd Sep 2017
Location: Ghetto of NJ
Posted: 12th Dec 2017 23:34
If it converted it to 10000000 that would be acceptable. I mainly set it that way because when I started to design the program I really wasn't sure what number I would need to get a good sample size. I don't believe I have optimization on to be honest but I could be wrong. I have had to manually turn it on in the past so I don't believe its the default setting on my VS.

I agree I believe it to be the message pump, Either that or the Arithmetic of simply adding 1 to X and then checking the value of X against TESTSIZE. Those currently are the only two things I can figure on that would cause such a swing between the two different loops however the C++ code does those same addition and check so its very reasonable to believe its something done to prevent lockups.


Seems to be the only line that really could be adding this many clock ticks.
28 MOV EBX IMM4 [9
28 CALL EBX ; CALL [dbprocore.dll ,?ProcessMessages@@YAKXZ
Sphere sphere = new Sphere(0.5f);
InsanelyRedundantJava insanelyredundantjava = new InsanelyRedundantJava(Redundancy1, Redundancy2);
zero32
1
Years of Service
User Offline
Joined: 28th Jul 2016
Location:
Posted: 13th Dec 2017 08:08 Edited at: 13th Dec 2017 08:12
Quote: "a next loop that knows its going to have an end somewhere"

about that...

translates to an infinite loop. (don't run this code, the programm will crash because it lacks error checking!)
but because this works, you could make an infinite loop and create a custom check to break out of it and it still takes a fraction of the time the other loops take.

your code shows the following times on my machine:
FOR NEXT: 19
WHILE: 170
REPEAT UNTIL: 160
GOTO: 160

and because the for loop works like that, this code

takes around 30ms to finish. still not a gold medal, but atleast better than the other loops.
"It is only slightly easier than changing all sugar in a cake into stevia after it has already been baked" -Bisqwit
Sedit
User Offline
Joined: 3rd Sep 2017
Location: Ghetto of NJ
Posted: 18th Dec 2017 05:28
30ms is fine and roughly what I was getting in C++. I already have come to the conclusion that the above is exactly what I would be doing from now on where speed is concerned. Nothing else makes sense really.

You can also make
For X = 0 to 1 Step -1

I believe the above will work also but I have not tested it.
Sphere sphere = new Sphere(0.5f);
InsanelyRedundantJava insanelyredundantjava = new InsanelyRedundantJava(Redundancy1, Redundancy2);
zero32
1
Years of Service
User Offline
Joined: 28th Jul 2016
Location:
Posted: 19th Dec 2017 10:35
Nice, i didn't think of using a negative step value.

Also i was thinking that, in theory, this is not an infinite loop. Because X is a signed integer it will wrap to a positive value and eventualy x will become 1. so if you need more than 4294967295 cycles, you would need to put the for loop inside of a normal do loop. It should not impact performance too much because the do loop will only be called once every 4294967295 cycles.
"It is only slightly easier than changing all sugar in a cake into stevia after it has already been baked" -Bisqwit
Chris Tate
DBPro Master
9
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 19th Dec 2017 11:15 Edited at: 19th Dec 2017 11:16
I see comment:

Quote: "your code shows the following times on my machine:
FOR NEXT: 19
WHILE: 170
REPEAT UNTIL: 160
GOTO: 160"


I insert trusty stopwatch snippet:



I see 10 fold improvement

In conclusion, I will continue to use only for loops where possible. Scrap the rest.

Thanks for the inspiration.
Sedit
User Offline
Joined: 3rd Sep 2017
Location: Ghetto of NJ
Posted: 20th Dec 2017 06:32
No problem, Glad I could be of some use, Lord knows the forum has been kind so me so it feels good to be able to give back even if its just a little something.

I like the Stopwatch BTW, Nice little addition.

I need to get back around to designing some additional test that are more complex. I really would like to pit Sparky Collision DLL against DBPro internal commands because I ran some basic test a while back and seen little improvement if any yet had a good amount of additional overhead. Its more then likely due to the way I was using sparky dll so it would be nice to setup some speed test to determine what works... What works better, and What the best way to do things is.

Collision is currently a huge bottle neck in DBPro from what I seen and if we can streamline that I honestly in my heart believe DBPro can hold its own with the big boys, The FOR loops are already on par with C++ which should come as little shock since its really only a couple simple ASM commands.

I think it basically boils down to this: If we really want to bring DBPro to its full potential, we NEED to find a way around every damn error catch that they provided to safeguard BASIC users. Once those are essentially turned off every other internal command I have seen is not bad.

Hell... I have been running DarkGDK and that so far has outperformed SDL.....SFML.... and WinGDI...... Thats kind of insane considering the slag people throw at DarkGDK. I get it, those other libraries do give you alot more power at the end of the day but the things that have to be done to get it to perform better then a couple simple GDK commands is not something to ignore.
Sphere sphere = new Sphere(0.5f);
InsanelyRedundantJava insanelyredundantjava = new InsanelyRedundantJava(Redundancy1, Redundancy2);
Chris Tate
DBPro Master
9
Years of Service
User Offline
Joined: 29th Aug 2008
Location: London, England
Posted: 20th Dec 2017 08:30
Quote: "Collision is currently a huge bottle neck in DBPro from what I seen and if we can streamline that I honestly in my heart believe DBPro can hold its own with the big boys, The FOR loops are already on par with C++ which should come as little shock since its really only a couple simple ASM commands."


Yes it is a bottle neck, not quite as bad as bone animation once was, now with the emergence of jGPU skin.

I am using PhysX plugins to get the bulk of the collision done on the PPU. For other situations where I need more consistency and control, I merge all geometry in as few objects as possible for Sparkys collision to optimize efficiently.

We could do with a user friendly plugin which reduces the learning curve and complexity of this process, and systematizes all CPU and PPU collision functions. PhysX functions can be inconsistent; Sparkys collision is more consistent but CPU centric.

Quote: "Hell... I have been running DarkGDK and that so far has outperformed SDL.....SFML.... and WinGDI...... Thats kind of insane considering the slag people throw at DarkGDK."


Some people do not realise that the grass ALWAYS greener on the other side of the fence.
Stab in the Dark software
Valued Member
15
Years of Service
User Offline
Joined: 12th Dec 2002
Playing: Badges, I don't need no stinkin badges
Posted: 20th Dec 2017 16:17 Edited at: 20th Dec 2017 16:18
Quote: "This is interesting since I have long considered converting Milkshape 3D models to X Format or DBO for Dark Basic Pro to be a pain in the ass. I find that all too often models come out with wrongly adjusted joints, missing joints or other inconsistencies. Right now in order to Export from Milkshape3D I need to save, Import into Fragmotion (a program that requires typing the lords prayer, you read that right, once a week to even launch), play around with a few settings, and export to X Format. A one shot converter from MS3D to DBO would be quite nice. Do you have any resource that might be helpful for this? A layout of the DBO file format for example? I remember a long time ago seeing a resource discussed that."


Mage
I have attached an old project that loaded a milkshape model into DBPro. It was almost finished except the animation had
a bug somewhere. Maybe you can finish it. It loaded models extremely fast as it by passed the DBPro load object.
The coffee is lovely dark and deep,and I have code to write before I sleep.

Attachments

Login to view attachments

Login to post a reply

Server time is: 2018-05-26 13:08:53
Your offset time is: 2018-05-26 13:08:53