• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Oolala

Worst profiler results

10 posts in this topic

Question is pretty straight-forward:

 

You just finished writing a bit of code, and it doesn't quite meet your performance demands, so you run it through a profiler to find out where you need to trim fat.  What are you really hoping doesn't show up in your profiler results?

 

For me, I just got the result that memory allocation is accounting for roughly 75% of my runtime.  This really is one of those things that I hope not to see, mostly because it's one of those kinds of problems that can't really be addressed in one place, and is a sign that everything everywhere needs changed.

0

Share this post


Link to post
Share on other sites

I just got the result that memory allocation is accounting for roughly 75% of my runtime.

Dynamic memory allocations are expensive. Heap fragmentation is devastating. Analyze your objects' lifetimes carefully. Use the stack where it makes sense (whenever an object's lifetime is FILO ordered), object pooling where it makes sense, and avoid frequent heap allocations by reserving the size of containers before using them.
0

Share this post


Link to post
Share on other sites

I have one fear when profiling. I fear that when I run it, nothing interesting shows up. Not hot spots, no obvious mistakes, no clear points to tackle. Just a nice even trace with lots of things taking up small amounts of time to do small things. Because optimizing that is the stuff of nightmares.

 

Also, any time I see large amounts of time spent in middleware or especially the graphics driver is likely to be hell. 

Edited by Promit
0

Share this post


Link to post
Share on other sites


You just finished writing a bit of code, and it doesn't quite meet your performance demands, so you run it through a profiler to find out where you need to trim fat.  What are you really hoping doesn't show up in your profiler results?
FifoFullCallback sad.png
0

Share this post


Link to post
Share on other sites

You just finished writing a bit of code, and it doesn't quite meet your performance demands, so you run it through a profiler to find out where you need to trim fat.  What are you really hoping doesn't show up in your profiler results?

Seeing nothing big is a serious one for me. I've done a lot of profiling and instrumenting of code, especially on some code bases destined for 20MHz and 66MHz processor systems. You can pick out the low hanging fruit pretty quickly.

What is devastating to me is finding hundreds or even thousands of tiny things, each with a cost that is only slightly too high, and each requiring a manual effort to fix.

 
For me, I just got the result that memory allocation is accounting for roughly 75% of my runtime.  This really is one of those things that I hope not to see, mostly because it's one of those kinds of problems that can't really be addressed in one place, and is a sign that everything everywhere needs changed.

That one is usually pretty simple. Count yourself lucky.

Assuming your profiler lets you sort by caller you can usually navigate quickly up the tree to find a small number of serious offenders. If the profiler itself doesn't do that (most do) then export your data into a big spreadsheet with calling data, use an Excel pivot table and play with it until you discover the offenders.

If this is the first pass through the code base there are a few common patterns. One common pattern is not reserving space in dynamic arrays (such as std::vector), instead simply adding items one at a time causing a large number of resizes. Usually these are evidenced by a brief stutter as the system drops a frame or two doing twenty thousand allocations. Another is the frequent creation of temporary objects, and since it is a performance concern it is likely happening in a relatively tight loop, so it is probably just a single location where you need to adjust object lifetimes. It may be a resource that is frequently being created in destroyed where a cache or persistent buffer would help. Or it could be a memory leak, premature object release and allocation, or similar problem.

All of those problems can be quickly identified with a good profiler. With 75% of your time spent in the allocator it should be glaringly obvious from the profile which functions need examination.
0

Share this post


Link to post
Share on other sites

Man, allocation is one of my [b]favorite[/b] profiler results, because it's basically trivial to change to better allocation strategies without rewriting a ton of code. You know exactly what you need to hit and you should ideally also know its usage patterns well enough to know immediately how to pick a better allocation scheme. It's like free performance.

 

Algorithmic improvements are a little worse, because they require hitting more code to improve; but they usually are only painful to me in the sense that they mean I made a dumb implementation choice up-front.

 

Past that is micro-optimization, where I have to do fiddly stupid things to try and squeeze out a few thousand cycles here and there, deep in some hot inner loop or something.

 

But I'm in agreement with earlier posters in that seeing [i]nothing[/i] is by far the worst. A similar cousin is seeing only calls that block inside the kernel, such as waiting on mutexes in a multithreaded program. Seeing only blocking calls/suspended threads means you're going to have a nasty time finding the actual [i]performance[/i] problem, because your wall-clock performance is dominated by not doing [i]anything[/i].

0

Share this post


Link to post
Share on other sites

I agree, seeing nothing would be worse.

 

The reason that I hate seeing 'new' float to the top of stuff is mostly because it almost guarantees me having to make a bunch of tiny tweaks in a bunch of tiny places to implement either a pooling mechanism, or a more intelligent copy-by-value mechanism for composite classes.  The second one is that which is currently killing me.  It either ends up meaning a few high-level structural changes to things, or a whole bunch of small and annoying changes in a bunch of places.

 

Normally my first pass on code is sort of written to the algorithmic complexity of the problem at hand, and not really taking into consideration performance much.  Seeing "new" at the top of my profiler hot-spot list is pretty much the computer telling me "no", and demanding that I now mire myself in the fine-grained performance details.  Admittedly, there are worse things the profiler can tell me, but this is always an annoying one that tends to mean far-reaching changes.

 

Yes though, seeing nothing is definitely worse.  Once got a profiler result that had not a single hit over 0.1% without counting children in the call graph.  That one turned out to be not so bad because there were some very high-level changes that could be made that made a big impact, but it wasn't obvious from the profiler results.

 

Sounds like some others are working on embedded systems, in which case the profiler can't hurt you any more than you're already used to being hurt on a daily basis.  Embedded systems are so painful in general.  Did some work on FPGA & cpu hybrid systems a while back, and it took so much work to get even the smallest things done.

0

Share this post


Link to post
Share on other sites

There are three situations I fear:

  1. The one mentioned: Lots of small things adding up (aka nothing "big" to focus on). This is by far fear #1
  2. Everything is a disaster: There are so many "big" things, the code is so badly written it's just better to rewrite from scratch. It's very similar to #1 (if everything's big, nothing's big).  But the situation is so bad, it needs to be put in its own category.
  3. The "big" things can't be optimized further: Something big is showing up on the profiler, but it is already cache friendly, SIMD optimized, and multithreaded. The reason it's showing up is because... well, it's the nature of the job being performed. There's just too much data to process. The only solution is to search for other algorithmic optimizations, but you have a hard time thinking of anything better than the algo being used. Fortunately this one is really hard to happen, because rarely I see code so well written and designed. Where I see this problem the most is in emulators.
Edited by Matias Goldberg
0

Share this post


Link to post
Share on other sites

I'd agree with all the 'nothing' and 'lots of small things' above but I'd also like to add one more to the mix; something that you caused ;)

I learned years ago to just assume I caused all the problems. It saves time.

Usually I didn't, but when you approach it like "What did I break, and how can I fix it?" it is much more useful than taking time to assign blame to others. Also it looks better to managers.

If it is something particularly nasty you can check version control when done, but most of the time isn't worth it. I often respond to queries about broken systems with "I wonder how I broke that..." because in some code bases a change in one place really can cause unexpected behavior in the most bizarre places. Being someone who submits a lot of changes affecting core functionality also means you are likely to break other people's stuff. A GPE working on the fringes usually only breaks his own stuff.

One tech lead I worked with had an interesting viewpoint. As developers grow in skill, experience, and domain, the bugs they cause should be even bigger, more powerful, and harder to fix. A good developer will constantly challenge himself. Bugs usually require more brainpower to find and fix than to write, and if some tricky bug took the full brainpower of a senior engineer to construct you know it will be nasty to fix. A junior engineer who breaks the build with a missing semicolon is fine. When a senior engineer breaks the build you can tell they are doing their job well when the breakage is a subtle change that takes the entire team out for three days and five people hunting through the code can't find the bug even after isolating the specific change that broke it.
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0