Product Chat / Lees Community Challenge

Author
Message
LeeBamber
TGC Lead Developer
24
Years of Service
User Offline
Joined: 21st Jan 2000
Location: England
Posted: 13th Mar 2014 19:41 Edited at: 13th Mar 2014 19:42
Hi Guys,



Just about to finish up on performance related work for GDC and move onto visuals for a day or two. Before I do however there is one horrible bottle neck which takes the engine from 80 fps down to 20 fps when 20 characters are surrounding the player. The cause of this horrible slow down is this code:



// find key

DWORD dwKey = 0;

DWORD dwKeyMax = pAnim->dwNumPositionKeys;

for ( int i = 0; i < ( int ) dwKeyMax; i++ )

{

if ( pAnim->pPositionKeys [ i ].dwTime <= fTime )

dwKey = i;

else

break;

}




As you can see, for every frame, in every object, every cycle, I have to find the correct key frame index based on the fTime value. It's expensive and silly. I am looking for ideas how this code can be improved to return almost instantly the correct key index based on what the fTime value is. Good luck!

PC SPECS: Windows 7 Ultimate 64-bit, Intel Core i7 920, NVIDIA Geforce 650GTX Ti Boost 2GB GPU, 6GB RAM

Colosso
11
Years of Service
User Offline
Joined: 26th Feb 2013
Location:
Posted: 14th Mar 2014 00:15
Sorry Lee! I haven't programed anything in years. That is why I use FPSC so I don't have to reinvent the wheel. Great stuff your doing here though. I can't wait for more!



Dr. Colosso
Clonkex
AGK Tool Maker
14
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 14th Mar 2014 08:12 Edited at: 14th Mar 2014 13:00
Well, first of all, I think you should have posted this on the TGC forums as most people go there instead of here and most people here are likely not coders, but anyway...



This is an interesting problem. If the keys were guaranteed to be equal distances apart time-wise, you could simply interpolate the time between 0 and the largest time to find which key, but I assume the keys can be anywhere and everywhere. This makes it a fair bit more difficult.



So the idea I've come up with is basically to create a branching system. It could (depending on implementation....the method I explain below would use no extra memory) use a small amount more memory, but could drastically improve speed.



This would only (UPDATE: When I say only, I mean mostly - it could actually speed up all objects) help objects with a fair number of keyframes, such as characters, but I assume they have around 700-1000....the greater the number, the greater the speed increase. A simple check before the loop could decide whether to use the old brute-force system (which may be faster for objects with very few frames).



Let's see if I'm capable of coming up with a plugin replacement for the current code, in my head, without testing and without really wanting to do this....



*several hours later*



I think this should work. It's mostly untested (although I did run through the code by hand line by line with notepad to record variable states ). You should be able to replace the exact code you showed us with this code and it will be instantly working and instantly faster.



Here's the new code:







You're welcome

PM
LeeBamber
TGC Lead Developer
24
Years of Service
User Offline
Joined: 21st Jan 2000
Location: England
Posted: 15th Mar 2014 04:10
Thanks Clonkex, just what I needed and a good solution! Here is the final draft of it which is now powering MUCH faster animation processing in the Reloaded engine:







As you can see, I added in some stuff to remember the last keyframe and do a quick early exit if it's just stomping through the frames. If you see further speed improvements in the above, don't be afraid to post them here

PC SPECS: Windows 7 Ultimate 64-bit, Intel Core i7 920, NVIDIA Geforce 650GTX Ti Boost 2GB GPU, 6GB RAM

Clonkex
AGK Tool Maker
14
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 15th Mar 2014 07:25 Edited at: 15th Mar 2014 07:34
LeeBamber wrote: "I added in some stuff to remember the last keyframe and do a quick early exit if it's just stomping through the frames."




Ah, excellent idea! Can't believe I didn't think of that already



I'm very glad you understood how my code worked and were able to improve it. So often code from another programmer can only be understood by said programmer



I had a look through, and I can see you've made some quick optimisations that I missed... for example, me likes:





You're clearly a more experienced programmer than I (Although that's probably obvious given you wrote the language I learned on )

PM
DVader
20
Years of Service
User Offline
Joined: 28th Jan 2004
Location:
Posted: 16th Mar 2014 16:50
Not being a C++ programmer I was slightly lost at -> That would be nonsense in basic ;p Glad you understood enough to make a suggestion Clonkex. I figured I'd forget it, when I had to look up -> ;P

Clonkex
AGK Tool Maker
14
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 17th Mar 2014 02:38
DVader wrote: "Not being a C++ programmer I was slightly lost at -> That would be nonsense in basic ;p Glad you understood enough to make a suggestion Clonkex. I figured I'd forget it, when I had to look up -> ;P"




Haha I learned C++ a couple of years ago when I wanted to create plugins for DBPro.



'->' works the same way as a full stop in BASIC (when you have a custom Type). You use -> to access variables inside another variable, when the main variable is a number which points to a location in memory where the data is stored (a "pointer"), rather than containing the data itself. If the variable is not a pointer and contains the data itself, you use a full stop just like in BASIC

PM
BarZaTTacKS
10
Years of Service
User Offline
Joined: 3rd Feb 2014
Location:
Posted: 17th Mar 2014 20:39 Edited at: 17th Mar 2014 20:39
Asked a friend about this..



"how many is in pAnim->dwNumPositionKeys on average



side note

With out changing much if the times are sorted you can store the previous index from the last loop and start there if they are sorted in order.



if not, this will not work"
PM
Clonkex
AGK Tool Maker
14
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 19th Mar 2014 04:51 Edited at: 19th Mar 2014 06:02
BarZaTTacKS's friend wrote: "how many is in pAnim->dwNumPositionKeys on average"




It can be anything; normally I think it would be several hundred, maybe as many as 1000 or more, but I think usually several hundred.



BarZaTTacKS's friend wrote: "With out changing much if the times are sorted you can store the previous index from the last loop and start there if they are sorted in order."




They are sorted in order, yes, and the current (new) version of the code does start from the previous index.

PM
LeeBamber
TGC Lead Developer
24
Years of Service
User Offline
Joined: 21st Jan 2000
Location: England
Posted: 25th Mar 2014 03:58
It's amazing I still get a kick out of coding, even after 30 years It's also humbling to know I still need plenty of help and have more to learn!!

PC SPECS: Windows 7 Ultimate 64-bit, Intel Core i7 920, NVIDIA Geforce 9600 GT GPU, 6GB RAM

Clonkex
AGK Tool Maker
14
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 26th Mar 2014 14:33 Edited at: 26th Mar 2014 14:34
Quote: "It's amazing I still get a kick out of coding, even after 30 years"




Haha, just as well! We need you to like coding!



Quote: "It's also humbling to know I still need plenty of help and have more to learn!!"




We're always glad to help! Just remember, if you want me to help specifically, make sure you say something in the blog posts or email me directly; I don't normally check this forum for new threads.

PM
Seditious
11
Years of Service
User Offline
Joined: 2nd Aug 2013
Location:
Posted: 26th Mar 2014 17:11 Edited at: 26th Mar 2014 17:20
Use indexing. Decide on a minimum granularity for fTime and fill an array with key frames, where the index represents the time.



Although storing the last index should be sufficient.
PM
Clonkex
AGK Tool Maker
14
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 27th Mar 2014 12:07
Seditious wrote: "Use indexing. Decide on a minimum granularity for fTime and fill an array with key frames, where the index represents the time."




If you're saying what I think you're saying, this won't work. The keyframes are not linearly spaced; that is, they can be clumped together in random groups, so anything that assumes they are evenly spaced won't work.

PM
Seditious
11
Years of Service
User Offline
Joined: 2nd Aug 2013
Location:
Posted: 28th Mar 2014 14:13 Edited at: 28th Mar 2014 14:15
Quote: "keyframes are not linearly spaced; that is, they can be clumped together in random groups, so anything that assumes they are evenly spaced won't work."




I know, hence why I mentioned deciding on a minimum granularity, so you don't miss any frames that slip through the cracks.
PM
Clonkex
AGK Tool Maker
14
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 28th Mar 2014 23:55
Seditious wrote: "I know, hence why I mentioned deciding on a minimum granularity, so you don't miss any frames that slip through the cracks."




Hmm...it seems I don't know what you're saying...

PM
Seditious
11
Years of Service
User Offline
Joined: 2nd Aug 2013
Location:
Posted: 29th Mar 2014 11:13
Quote: "Hmm...it seems I don't know what you're saying... "




Well for example decide on how accurate/fine you want to track the animation (for example a granularity of 0.05ms means it'll be accurate to 0.05ms. Create an array of size maximum time * (1.0 / granularity) and fill it with key frames. Then just reference the array with the elapsed time:



frame = frameList(time)



And the array will appear like this:







It doesn't really have many advantages over just storing the last frame though, and would only benefit from very specific circumstances.
PM
Clonkex
AGK Tool Maker
14
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 29th Mar 2014 11:45
Seditious wrote: "It doesn't really have many advantages over just storing the last frame though"




I'll say. That method involves using an array possibly hundreds of times the number of keyframes, depending on the gaps between keyframes. Very inefficient in my opinion, but it would work, I think.



Still not sure what you mean by "storing the last frame", though

PM
Seditious
11
Years of Service
User Offline
Joined: 2nd Aug 2013
Location:
Posted: 29th Mar 2014 23:30
Quote: "I'll say. That method involves using an array possibly hundreds of times the number of keyframes, depending on the gaps between keyframes."




It's no problem unless you live in the '80s and only have 16kb of memory.



Quote: "Still not sure what you mean by "storing the last frame", though"




I mean iterating from the last key frame, as Lee mentioned doing.
PM
Clonkex
AGK Tool Maker
14
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 29th Mar 2014 23:42
Seditious wrote: "It's no problem unless you live in the '80s and only have 16kb of memory."




I suppose. It just irks me, using more memory than I have to. Particularly in a thing like Reloaded which struggles to fit into ram as it is.



Seditious wrote: "I mean iterating from the last key frame, as Lee mentioned doing."




OOOOHHHHHH, you don't mean the END frame, you mean the last frame checked! Totally confused me

PM
Seditious
11
Years of Service
User Offline
Joined: 2nd Aug 2013
Location:
Posted: 1st Apr 2014 00:48
Quote: "I suppose. It just irks me, using more memory than I have to. Particularly in a thing like Reloaded which struggles to fit into ram as it is."




I certainly understand that (and feel the same way), but in cases where you want absolute speed (and admittedly this isn't quite an appropriate one) it's best to be generous with memory and create look-up tables and such when possible.
PM

Login to post a reply

Server time is: 2024-11-24 03:04:22
Your offset time is: 2024-11-24 03:04:22