🔒 Locked
Calculating performance ?
Advertisement
Original Post
Hello all. I am having trouble predicting the hardware limitations for my code. Let me explain. I am working with a friend on a 2d RGP, we have multiplayer support. Our main concern at this time is working on the server we dont know how much raw calculationpower our ideas will need. Is there some math behind this to help, as how many lines of code / second.. or something ? Like, can the server loop thru all the players every gameloop, is that to much, how much more can we add and so on. We want to design the ideas on paper before coding, so trial and error isnt the best way to go I feel. Network traffic is fine, since we know how many bytes data take and needs to be sent and so on, it's more a question of not hogging all the server capacity with for/while loops and so on.. Hope I can get some hints.
I'd say as long as you come up with a sensible design on paper, looking for optimisations *before* writing the code is a Bad Thing (TM). As long as you don't do something ridiculously inefficient in your code (and even if you do), the best bet is to get your design coded first, stress test it with a variety of players and conditions, then profile, profile, profile!
The profiling will identify where most of the code execution is taking place, and it's only there you will need/want to optimise.
A very wise quote in this case is:
There's not much point looking for optimisations until you know which 10% of the code this is going to be.
..
Having said all that, if you really want a few speed-related tips, I'd say avoid nested inner loops (a loop within a loop within a loop, etc.), these can end up taking the most time to process. And it's not really how much code you have that will determine how long it takes to run, it's what the code is doing that may take a long time to process. A good example is read/write operations to the hard disk takes much, much longer than reading and writing to memory. MUCH longer.
The profiling will identify where most of the code execution is taking place, and it's only there you will need/want to optimise.
A very wise quote in this case is:
Quote:
90% of the code only runs for 10% of the time
There's not much point looking for optimisations until you know which 10% of the code this is going to be.
..
Having said all that, if you really want a few speed-related tips, I'd say avoid nested inner loops (a loop within a loop within a loop, etc.), these can end up taking the most time to process. And it's not really how much code you have that will determine how long it takes to run, it's what the code is doing that may take a long time to process. A good example is read/write operations to the hard disk takes much, much longer than reading and writing to memory. MUCH longer.
"lines of code / second" depends a lot on what those lines are doing - but with CPUs running at gigahertz, it's not unreasonable to assume they could do something in the order of a billion operations per second. Typically it's not worth caring about code unless it's running millions of times: e.g. pathfinding may become an issue, because it might have to process every tile in the world and it might be called frequently for every character that is walking around; but simply looping over a few dozen players and doing some not-very-loopy calculations should always be fine.
I do think it's sensible to consider performance during the design, but you can't tell where the real problems are until you try writing and profiling the code to see what's going slowly. It's best to design in a way that makes future design changes easy, especially around the areas where problems are expected, which is where experience helps - e.g. if you know pathfinding has been a problem before, you'll want to be careful to make it easy to optimise in the future, maybe by making it run at a variable framerate independent of the normal simulation update rate, which is probably a bit easier if you design around that flexibility at the start; and e.g. if you want to write AI in a scripting language, that'll be very slow and you'd want to minimise the number of times you have to call it, and not design it so that every creature in the world gets to run some script code on every frame.
But in any case, it's still really hard to estimate performance during the design process, so just take account of that necessary lack of knowledge when you're doing the design [smile]
I do think it's sensible to consider performance during the design, but you can't tell where the real problems are until you try writing and profiling the code to see what's going slowly. It's best to design in a way that makes future design changes easy, especially around the areas where problems are expected, which is where experience helps - e.g. if you know pathfinding has been a problem before, you'll want to be careful to make it easy to optimise in the future, maybe by making it run at a variable framerate independent of the normal simulation update rate, which is probably a bit easier if you design around that flexibility at the start; and e.g. if you want to write AI in a scripting language, that'll be very slow and you'd want to minimise the number of times you have to call it, and not design it so that every creature in the world gets to run some script code on every frame.
But in any case, it's still really hard to estimate performance during the design process, so just take account of that necessary lack of knowledge when you're doing the design [smile]
Thanks guys, if nothing else theese posts gave me confidence to move forward with the coding.
I guess it's reasonable to do that first and see if there even is a problem.
I guess what had me worried was will 300.000 variable changes impact much. But if its in the ballpark of bilions then I am really not worried. :)
thanks again
I guess it's reasonable to do that first and see if there even is a problem.
I guess what had me worried was will 300.000 variable changes impact much. But if its in the ballpark of bilions then I am really not worried. :)
thanks again
Quote:
Original post by Twixly
Thanks guys, if nothing else theese posts gave me confidence to move forward with the coding.
I guess it's reasonable to do that first and see if there even is a problem.
I guess what had me worried was will 300.000 variable changes impact much. But if its in the ballpark of bilions then I am really not worried. :)
thanks again
A variable change is not just a single operation. Memory accesses are definitely very expensive and it's one of the things high-performance assembly coders make sure to avoid if possible, and I'd bet that you also does other things (function calls, pointer dereferencing, math functions and virtual function calls are all quite expensive features). Before we can determine whether your approach seems reasonable you need to tell us what you want to do.
Ok, sorry I should been more clear, it's not actually creating or assigning variables. Atleast not so many, simple selecting a few pointers from an vector.
What I want to do is loop thru and vector with maybe 3000 monsters (not sure how many yet), check their status with a simple :
if(monster == active) send monster pointer to a new vector (queue to process)
What I am missing in C++ or any other language is a good way to select data from my vectors, I am used to databases from work so "Select * from monsters where active = true" is what I am thinking of, but the more I think of it a database must surely go thru all entries aswell to check if Y=1 ?
Anyways, let's stay on subject, hope it clearifies it a little.
What I want to do is loop thru and vector with maybe 3000 monsters (not sure how many yet), check their status with a simple :
if(monster == active) send monster pointer to a new vector (queue to process)
What I am missing in C++ or any other language is a good way to select data from my vectors, I am used to databases from work so "Select * from monsters where active = true" is what I am thinking of, but the more I think of it a database must surely go thru all entries aswell to check if Y=1 ?
Anyways, let's stay on subject, hope it clearifies it a little.
Quote:
Original post by Twixly
Ok, sorry I should been more clear, it's not actually creating or assigning variables. Atleast not so many, simple selecting a few pointers from an vector.
What I want to do is loop thru and vector with maybe 3000 monsters (not sure how many yet), check their status with a simple :
if(monster == active) send monster pointer to a new vector (queue to process)
What I am missing in C++ or any other language is a good way to select data from my vectors, I am used to databases from work so "Select * from monsters where active = true" is what I am thinking of, but the more I think of it a database must surely go thru all entries aswell to check if Y=1 ?
Anyways, let's stay on subject, hope it clearifies it a little.
no a database won't always have to go through all the entries (depends on how the table is organized).
in general you can make searches alot faster if the data is sorted (you can google for binary search for example)
the downside to sorting the data is ofcourse that insertion aswell as modification of elements will take more time.
a good rule of thumb:
If the data is static it should always be sorted
if it is dynamic it should be sorted if you make searches alot more often than you make modifications.
some decent sorted containers in C++ is std::set and std::map (there are others aswell)
Quote:
Original post by Twixly
What I want to do is loop thru and vector with maybe 3000 monsters (not sure how many yet), check their status with a simple :
Rather than looping through all monsters and checking their status, you only need to make a modification once for each monster when it becomes active or inactive, and keep this information in a strucutre like a map or set as mentioned. To demonstrate:
[source lang=cpp]Monster::setActive(bool status){ if (active == true) activeMonsters.add(this); else activeMonsters.remove(this); this.active = status;}Then whenever you want to process your active monsters, iterate over each member of the
activeMonsters set. I would use a map with the key as a unique identifier to make searching for a particular monster easier.
Looping through 3000 items per frame and doing a tiny bit of work (checking a variable, pushing onto a queue) is not going to be a serious problem. Thinking about implementation details like std::map at this stage is probably premature optimisation [smile]
I'm working on a game where the entity manager loops over all 4096 slots every frame to see if they're used, and it's fast enough that we haven't cared about trying to improve it. There was a problem when the game recursed down half a dozen levels of inherited script event handlers (doing a std::map lookup at each level) to find the 'tick' handler for every entity (including each tree and each rock) every frame, but even that was only halving the framerate. (The solution was to just remove the 'tick' event, because it was never actually used. The fastest code is the code that's never run...)
The bigger problems come when you e.g. test for collisions of every entity against every other entity, and end up with millions of tests; thousands usually doesn't matter.
As long as the design isn't planning anything incredibly slow (which it doesn't sound like it is), I'd agree that the best approach is just to stick with that and implement it and see how it runs, and then measure it and optimise it if (and only if) it turns out to be necessary.
I'm working on a game where the entity manager loops over all 4096 slots every frame to see if they're used, and it's fast enough that we haven't cared about trying to improve it. There was a problem when the game recursed down half a dozen levels of inherited script event handlers (doing a std::map lookup at each level) to find the 'tick' handler for every entity (including each tree and each rock) every frame, but even that was only halving the framerate. (The solution was to just remove the 'tick' event, because it was never actually used. The fastest code is the code that's never run...)
The bigger problems come when you e.g. test for collisions of every entity against every other entity, and end up with millions of tests; thousands usually doesn't matter.
As long as the design isn't planning anything incredibly slow (which it doesn't sound like it is), I'd agree that the best approach is just to stick with that and implement it and see how it runs, and then measure it and optimise it if (and only if) it turns out to be necessary.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement