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 / Little things that affect FPS

Author
Message
Guruchild
23
Years of Service
User Offline
Joined: 13th May 2003
Location: United States
Posted: 4th Nov 2003 01:03
What are some better known little things one should not do in programming darkbasic to keep FPS from taking a hit?

For example, I experience a big hit if I try to change the font size and paste that text to the screen and then change it back for the rest of the text on the screen. What are others?

Anymore it seems I take huge hits in FPS by just adding small things. IT makes me wonder if I could improve performance with some knowledge.

I have a sign beside my door-hinge, that says nothing rhymes with orange.

Soul Defender: 75% GodMode RPG: 5%
Andy Igoe
23
Years of Service
User Offline
Joined: 6th Oct 2002
Location: United Kingdom
Posted: 4th Nov 2003 01:47
Massive scale exclusive conditional testing.

Yup, fancy word for a very simple thing.



As those of you who have seen my code know I am a big advocate of If...Else...EndIf structures. Such code structure allows massive sections of code to be conditionally excluded from the main loop so that code is only executed when it is needed.

It's the kind of thing that experienced programmers take for granted, for us it is automatic, but as a youngster I can remember writting programes where just about every line of code was executed every pass, and mostly that just isn't needed.

Also dynamic re-use of objects can allow you to reduce the number of objects being handled by DBPro, you can edit meshes and retexture 5 objects on the fly much faster than DB can handle 20 objects - and used correctly 5 objects can represent far more than 20 objects.

But the biggest speed increases of all that are very easy to implement...

set object cull objNo,1

Reverse face culling. This will about halve the number of polys being rendered.

And bigger yet, using objects with only one texture file. Dunno why, probably a graphics card pipeline issue that some techie will spend 8 pages explaining without giving a solution, but if you use an object with multiple texture files it displays much slower than the same object with just one texture file - even if all the other texture co-ordinates and UV mapping is identical, just reduce your textures to 1 image file.

Pneumatic Dryll
Guruchild
23
Years of Service
User Offline
Joined: 13th May 2003
Location: United States
Posted: 4th Nov 2003 02:40
That helped a little, some of those hints. Mainly making sure culling is set to everything you want it for. Before these modifications my game ran at 55 fps on my system. Now it runs at around 88 fps.

My system is a AMD XP, 1529MHz, RAM 512MB, RADEON 9800 PRO

I still think it could go faster.

I have a sign beside my door-hinge, that says nothing rhymes with orange.

Soul Defender: 75% GodMode RPG: 5%
Neophyte
23
Years of Service
User Offline
Joined: 23rd Feb 2003
Location: United States
Posted: 4th Nov 2003 06:19
@PneumaticDryll

"Dunno why, probably a graphics card pipeline issue that some techie will spend 8 pages explaining without giving a solution"

Texture chache thrashing.
Jess T
Retired Moderator
22
Years of Service
User Offline
Joined: 20th Sep 2003
Location: Over There... Kablam!
Posted: 4th Nov 2003 13:56
Quote: "But the biggest speed increases of all that are very easy to implement...

set object cull objNo,1

Reverse face culling. This will about halve the number of polys being rendered."


Ok... well, that boosted my FPS from 26 to... wait for it... 28!!!

anyone else got some suggestions? this could become a very usefull thread for those of us that aren't the best at speed optimization...


Team EOD :: Programmer/Logical Engineer/All-Round Nice Guy
STE
22
Years of Service
User Offline
Joined: 7th Oct 2003
Location:
Posted: 4th Nov 2003 14:32 Edited at: 4th Nov 2003 15:05
1) Use #Contants whenever you can instead of variables, for data that doesn't change.
This will save the program another trip to memory.

2) Use the smallest variable size you can get away with.
e.g. If a number goes from 1 to 100, use a "byte" variable, not an integer.
This means less memory usage and I general CPU instructions are quicker with smaller variable types too.

3) Use pre-calculation where possible for maths.
e.g. If you can hold Up & Right on the keyboard and move the character the same distance diagonally, don't have "DistanceToMove=Speed*sqrt(2)/2.0". Use the approximation "DistanceToMove=Speed*0.7071" instead.

All these optimisatins come from understanding what the computer is actually doing under the hood (and making a few assumptions about what the DBPro compiler is doing too). So learning about low level computer hardware is really the basis.

EDIT: Numbering corrected so I look like less of a prick.

STE ;¬!
Jess T
Retired Moderator
22
Years of Service
User Offline
Joined: 20th Sep 2003
Location: Over There... Kablam!
Posted: 4th Nov 2003 14:43
Lol... i love your numbering system there STE... 2)... 2)... 3)... LOL...

No offence meant... hehe


Team EOD :: Programmer/Logical Engineer/All-Round Nice Guy
IanM
Retired Moderator
23
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 4th Nov 2003 15:19 Edited at: 4th Nov 2003 15:22
First, I'll list a few machine considerations:

Correction for STE's second number 2. If you want speed from an Intel processor, stick to 32 bit variables. If the byte/word/boolean isn't on a 32 bit boundary, it'll be much slower.

On the same vein, learn to use types in arrays instead of using separate arrays to hold associated information (like you have to in DBC). This is because the processor prefetches information into the cache in batches of 32 bytes, and accessing the cache is faster than accessing memory directly. This means that if you are accessing several members of the type, they could already be in cache waiting for you.

Always try to read forward through your arrays so that the processors 'prefetch' mechanism is already reading the information you want to use later.

Don't overload your video memory - always leave space. If you don't, then objects/textures will be forced to be held in system memory and loaded/unloaded as required. Even at AGP speeds, this will be slow.

Don't overload your system memory - If you overfill, the data will be paged onto disk and loaded/unloaded as required.


Now a few general coding bits:

Move your calculations outside of loops. For example, in the perfect pixel collision function that ChipOne and I put together, the best speed increase was gained by completely rewriting the inner loops to simplify the address calculations for the memblocks. The inner loop has no multiplication in at all, the next lower has the minimum required to calculate the start of the next row of pixels.

Brute-force coding is not your friend ...

Don't search down an array for an entry - keep it sorted and use a binary search. More code, but far faster.

Don't use quicksort on an array that's already sorted when adding an item. Bubblesort the new item into place.

I'll post a bit more later
Scraggle
Moderator
23
Years of Service
User Offline
Joined: 10th Jul 2003
Location: Yorkshire
Posted: 4th Nov 2003 17:42
Here's a question that is related.

If using several identical objects (500 spheres for bullets in my case). Is it better/quicker to create them all at the start of the program and have them hidden until needed or create them as needed and deleted when not?

Sleep ... those little slices of death. How I loathe them! - Edgar Allen Poe
Scraggle
Moderator
23
Years of Service
User Offline
Joined: 10th Jul 2003
Location: Yorkshire
Posted: 4th Nov 2003 17:45
Quote: "But the biggest speed increases of all that are very easy to implement...

set object cull objNo,1

Reverse face culling. This will about halve the number of polys being rendered.
"


Should this be done when the object is created or should it be placed in the main code loop when the object is repositioned?

Thanks

Sleep ... those little slices of death. How I loathe them! - Edgar Allen Poe
Van B
Moderator
23
Years of Service
User Offline
Joined: 8th Oct 2002
Location: Sunnyvale
Posted: 4th Nov 2003 18:27
I suggest making a function to handle standard object types - like one for face culling, one for transparent textures (which usually need face culling disabled) etc etc. That way your program is more compact and takes less memory - making it faster. Always setup the object after loading too.

Here's a nice little one - check to see if an object is visible before deciding to hide it, like:

'To hide it
If object hidden(n)=1 then hide object n

'To show it
If object hidden(n)=0 then show object n

Not sure about that OBJECT HIDDEN bit, might be another command - but it's faster to check the hidden state of an object than it is to hide or show it - therefor hiding or showing objects when they are already in the required state is not wise.

Scraggle,
The very fastest way to handle all those bullets is with no objects at all, why not look into instant hit methods, more realistic anyway. If you need to see the bullets, then a sphere is the last thing you should use, a rotate plain with a round texture, ghosted perhaps, or a really low polygon mesh - Never a sphere, they're far too high poly. I would create them at initiation, creating objects is slower than showing them, but 500 us a helluva lot for poor old DB/DBPro.

People are often tempted to lock the frame rate on their games - but it's often a much better idea to impliment time based motion, so instead of something moving 1 unit per loop, it might move 100 units per second, this would iron out all the speed inconsistances and keep the gameplay going. The last thing you want is slowdown, with time based motion your PC can go as fast as it wants, and the engine will just get smoother if there's extra horsepower.

Precalculate as much as possible. For example, if your firing a bullet in an FPS, calculate where the bullet will land and how far away the destination is when you initilise the bullet - this means you only check the wall collision once, you have a preset destination that you can stick a bullet hole decal at, you don't need to check wall collision while the bullet is in flight - you only need to check for character collisions (which can be far easier and faster by using limb positions and bounding boxes).


Van-B


I laugh in the face of fate!
Scraggle
Moderator
23
Years of Service
User Offline
Joined: 10th Jul 2003
Location: Yorkshire
Posted: 4th Nov 2003 19:41
@Van B Thanks for the tips on bullets. My current project isn't realistic and I do need to see the bullets, however, although I am using 3D graphics my project is 2D so a flat mesh with a bullet texture will do - thanks

Quote: "Always setup the object after loading too.
"


Is that the answer to my second question? Is CULL OBJECT a one off command issued at object creation or does it need to be called each loop?

Thanks

Sleep ... those little slices of death. How I loathe them! - Edgar Allen Poe
Andy Igoe
23
Years of Service
User Offline
Joined: 6th Oct 2002
Location: United Kingdom
Posted: 5th Nov 2003 03:18
"This means less memory usage and I general CPU instructions are quicker with smaller variable types too."

Welcome to the world of the 32bit computer.

-*-


Quote: "500 spheres for bullets in my case"


No no no no no no no no no!

Repeat after me: "I will not use 500 sphere objects for bullets.".

This is probably where you are loosing most of your speed. Instead use variables to hold the position of the bullets and make 10-20 or so spheres and 10-20 or so plains which a circle texture. You might need to adjust the numbers a little depending upon how your game displays.

Yes it is a lot more work to code, yes it is significantly faster. To get an idea of how much faster temporarily use the hide object command on all your spheres and change the make object sphere command to make object plain of size 0,0 (not sure if this bit helps). What is the fps now?

Place the spheres where the nearest bullets are, place the plains where the next nearest bullets are and turn them to the camera.

Using this technique on all objects that reappear frequently in the game will allow you to exponentially increase the object density/population of your world. In one program I wrote in DBPro I placed a million objects on a matrix and it ran as fast as having 300 object...

The standard DBP make object sphere is reasonably high polygon, you might want to consider modelling a geosphere construct instead, you can reduce the poly count by about a third with a geosphere and not really loose any visual appearance. For a bullet which tends to be quite small I would even consider using a cone or cylinder for even less polygons.

And yes, cull object is a one off command.

Pneumatic Dryll
STE
22
Years of Service
User Offline
Joined: 7th Oct 2003
Location:
Posted: 6th Nov 2003 03:27
Not believing that I was wrong, I wrote this little program to test the speed of integer & boolean usage.



In this instance, Integer usage is ~twice as quick as boolean usage on a AMD Tbred 2400+.

Thanks for educating me people.

STE ;¬!
Andy Igoe
23
Years of Service
User Offline
Joined: 6th Oct 2002
Location: United Kingdom
Posted: 6th Nov 2003 08:09
Here's another one. You would think integers are faster than floats right? Yes of course they are, right?

Compare the speed of position object testObj,x,y,z and position object testObj,x#,y#,z#.

I haven't tested this one, I pulled it off the top of my head as an example, but what seems to happen within DBPro is that if a function like Position Object requires float information and you give it an integer - which you would think is faster - it isn't. DBPro has to convert the data.

Afterall, a float is stored in 32 bits of information...

Pneumatic Dryll
ICERGB
23
Years of Service
User Offline
Joined: 8th Nov 2002
Location: Canada
Posted: 6th Nov 2003 08:10
Quote: "On the same vein, learn to use types in arrays instead of using separate arrays to hold associated information (like you have to in DBC)."


How can I do this?
Could someone give me an example?

set object cull objNo,1
This will...?

TKS
Scraggle
Moderator
23
Years of Service
User Offline
Joined: 10th Jul 2003
Location: Yorkshire
Posted: 6th Nov 2003 09:28
Quote: "And yes, cull object is a one off command."


That suggests to me that for best FPS, CULL OBJECT should be called after any/all objects are created/loaded.

Is there a situation where that would not be desirable? If not why doesn't object culling happen automatically?

My latest project has no name - feel free to suggest one. Think 'Lunar Lander' with multiplayer, guns and bombs!

IanM
Retired Moderator
23
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 6th Nov 2003 09:30 Edited at: 6th Nov 2003 09:31
That's nothing to do with what you've quoted!

It's simply a statement that this code:



Is less efficient than this code:




This is purely because the accessing of the 'X' item in the type will cause the prefetch to pull the rest of information held in the type into the cache so that memory access will be much faster for the subsequent commands.

This will not be the case for the first version - the items will be spread out in memory, so you'll get no help from prefetch there.

Also, you would want to make sure that you access data from the front of the type first, as prefetch works by reading forward. So using the above example, you need your speed and direction to calculate updates for you x and y coords to be updated with slightly later.

This is also a good reason to use functions too ... the most accessed area of memory is generally the processes stack area, almost guaranteeing that the top of the stack is cached, and this is where your local variables are held ...

I was going to branch into one or two other things, but I seem to have run out of time
Guruchild
23
Years of Service
User Offline
Joined: 13th May 2003
Location: United States
Posted: 6th Nov 2003 09:59 Edited at: 6th Nov 2003 10:01
Thanks for all the tidbits. I'm sure everyone will benefit from the great info. Keep posting more if you have them!

Unfortunately for people like me working on the tail end of their first complete project, I am quickly learning writing a game takes less time than optimizing it. Perhaps future games will be coded more efficiently

I do tend to use a lot of if then else etc statements as switches in my loop. I thought this was newbish but I guess it turns out that wasn't such a bad idea.

I have a sign beside my door-hinge, that says nothing rhymes with orange.

Soul Defender: 75% GodMode RPG: 5%
las6
23
Years of Service
User Offline
Joined: 2nd Sep 2002
Location: Finland
Posted: 6th Nov 2003 12:44
agh!
first of all, that culling is really odd thing. Because as far as I know it is "1" by default. At least I've had to set it to "0" whenever I wanted to show the backfaces too. And I wouldn't have to do this, if it would be at zero by default.

and about that object hiding/displaying.
Quote: "If object hidden(n)=1 then hide object n"

I believe the command would be "Object Visible(n)=0", but it could be some another command too.
And, here's another thing:
Is it good to check the object visibility as this creates extra workload? And in cases where the visibility changes often, you'll end up using two commands instead of one.

The same problem goes everywhere. How much optimization and checks is too much? If you do too heavy VIS calculations realtime, those will slow the game down more than if you would have just shown the whole map.

Keyboard not detected. Press F1 to continue.
Jess T
Retired Moderator
22
Years of Service
User Offline
Joined: 20th Sep 2003
Location: Over There... Kablam!
Posted: 6th Nov 2003 13:44
A good one to use, that i almost alway use for multiplw objects is:

If Object In Screen(n) = 0 Then Hide Object n

This hides all the objects that aren't on the visible screen, which seems to help my programs alot...

Hope I Helped...


Team EOD :: Programmer/Logical Engineer/All-Round Nice Guy
Van B
Moderator
23
Years of Service
User Offline
Joined: 8th Oct 2002
Location: Sunnyvale
Posted: 6th Nov 2003 13:46
That's a good point Las6, personally, I like to use arrays a lot - like if I had 20 enemy objects and wanted to occlude them when they're not in the screen, I'd use an array to signify if I'd hidden them already or not instead of using Object Visible.

As for visual calculations, I tend to use arrays - a simple 2D array referencing object numbers is often all you need, just check the camera position in relation to the array and make the relevant objects visible or not visible.


Van-B


I laugh in the face of fate!
las6
23
Years of Service
User Offline
Joined: 2nd Sep 2002
Location: Finland
Posted: 6th Nov 2003 13:54
Yep, I have used the array method for storing the visibility info as I find it a bit stupid to check it every time (resulting in many checks per loop, that is)

Van-B, that is okay... to some point. But then again, it depends heavily on what kind of map/level you use. Can you have multiple objects per array location. if so, how many? and so on...

Keyboard not detected. Press F1 to continue.
Van B
Moderator
23
Years of Service
User Offline
Joined: 8th Oct 2002
Location: Sunnyvale
Posted: 6th Nov 2003 15:08
Well, for multiple objects I'd most likely use a manual bounding box around each object, like an array with the dimensions of the bounding box and it's visibility state. Then when I want to exclude the geometry I'd run a check, really just check to see if the camera is inside the bounding box, and if so - make sure the object is visible. I'd probably run through the array of objects every so often to make sure it was hiding the objects again, you would'nt want to hide everything first. I think that doing it this way is less taxing on the processor than BSP systems, plus the extra control is a huge bonus, like showing a part of a level all the time (say a lamp post of something in the distance. I'd only use a 2D array VIS system on terrain, but it could be used on a level if it's split up into a rough grid too. In real terms, a level could be made from about 40 components, stepping through 40 bounding box checks and even visibility checks won't slow your program down too much, the FPS boost will more than make up for it. Also - only checking the nearby objects for collision, which could use the same array system would be a massive speed boost as opposed to checking for collision on a whole level - especially if you use DBPro's build in collision commands of course, I tend to avoid them like a leper with dandruff.


Van-B


I laugh in the face of fate!
Black Hydra
22
Years of Service
User Offline
Joined: 2nd Oct 2003
Location:
Posted: 6th Nov 2003 22:27
Heres one thing I think might help.

You said you loaded 500 bullet spheres. That seems a bit excessive. Not the number but the polygons. Excuse me if I am wrong in saying this but...

If you used textured planes wouldn't that signifigantly alter the FPS. If you made it so there x/y axis was always facing you and they were textured with a shaded picture. You would think it would speed things up. I mean doesn't a plane have 2 (or 4.. not sure) polygons in it? A sphere has tons more...

Again I am a newb to the 3D graphics side of prgramming so excuse me if I am wrong.
las6
23
Years of Service
User Offline
Joined: 2nd Sep 2002
Location: Finland
Posted: 7th Nov 2003 08:56
You are right, but that was pointed out many times before.

And yeah, using 500 bullets is a bit excessive. Perhaps you could scale that number down and make one bullet more effective. Like 1 bullet could represent 10 in real life. Oh wait, 10 real life bullets in FPS game. Now that sounds better.

Van-B, DBpro's inbuilt-collision, what's that?
Really, never used ANY collision commands, in DB or DBpro. So I wouldn't think of it now, either.

Finding that optimum level between optimization calculations and brute force methods is just tricky. Too much real-time "optimization" could actually slow your game down. Especially when the hardware gets more powerfull.. (gfx cards, you know)

Keyboard not detected. Press F1 to continue.
qwe
22
Years of Service
User Offline
Joined: 3rd Sep 2003
Location: place
Posted: 12th Nov 2003 23:43
in my game, for things i dont need to do every loop but need every second or so, i have if time=1 or time=50 then do the command..(time is inc'd each loop, and is set back to 1 when it reaches 100) this cuts down on calculations.. for example better to get the distance every 50'th loop (5/6th of a second on my game) then every loop

also i have a zones/regions system. if the object isnt in same zone, usually i dont need to do calculations for it.
ZomBfied
23
Years of Service
User Offline
Joined: 2nd Oct 2002
Location:
Posted: 14th Nov 2003 03:00
Why use spheres for bullets? ghosted plains look oh-so much better and all you bullets can have fewer poligons than a single sphere!

No more spheres for bullets!
Ian T
23
Years of Service
User Offline
Joined: 12th Sep 2002
Location: Around
Posted: 14th Nov 2003 04:12
Don't use spheres for ANYTHING but the sky. Stay minimalistic with small objects !

--Mouse: Famous (Avatarless) Fighting Furball

A very nice %it, indeed.
qwe
22
Years of Service
User Offline
Joined: 3rd Sep 2003
Location: place
Posted: 14th Nov 2003 04:47
i use a skybox
ZomBfied
23
Years of Service
User Offline
Joined: 2nd Oct 2002
Location:
Posted: 15th Nov 2003 08:08 Edited at: 16th Nov 2003 06:04
Hey I just realized... you don't have to check for bullet hitting the level every single loop! Just get the distance once and let 'er rip --when it reaches that distance, it hit's the level (if it's not a moving thing that is) you then just have to check for bullet hitting entities.


Oh wait andi ego said that up there a few posts back... Damn beat me to it!
AlecM
23
Years of Service
User Offline
Joined: 26th Aug 2002
Location: Concord, MA
Posted: 15th Nov 2003 08:55
"1529Mhz" ?? How does your processor get that for the clock? FSB and multiplyer would have to be at whacky settings Mabye im wrong though but it seems like a very odd number.

[P4 2.8C @ 3.03 with an 866mhz FSB:: MSI Neo-2LS running PAT:: 1gb Mushkin PC-3500 DDR High Perf level 2@ 2,2,2 :: ATI Radeon9800ProAIW :: 120Gb SeagateBarracuda 7,200RPM SATA HD :: Antec Plus1080AMG]
deX
22
Years of Service
User Offline
Joined: 12th Nov 2003
Location:
Posted: 15th Nov 2003 12:18
gad dang frogger, your fsb is faster than my processor
sorry, off topic


-deX
Philip
23
Years of Service
User Offline
Joined: 15th Jun 2003
Location: United Kingdom
Posted: 17th Nov 2003 13:03
Skyboxes are slower than skyspheres. Yes, they are. Don't ask me why. Seems counter-intuitive to me.

Philip

What do you mean, bears aren't supposed to wear hats and a tie?
qwe
22
Years of Service
User Offline
Joined: 3rd Sep 2003
Location: place
Posted: 17th Nov 2003 16:34 Edited at: 4th Dec 2003 00:39
no they arent
or could you explain urself??

Login to post a reply

Server time is: 2026-07-26 20:16:37
Your offset time is: 2026-07-26 20:16:37