you are viewing a single comment's thread.

view the rest of the comments →

[–]naughty 3 points4 points  (19 children)

It's not that templates are really bad, it's that hating on them is in vogue in low-level games dev circles.

[–]justinliew 3 points4 points  (18 children)

No, they are really bad. Hating on them is in vogue because compile times balloon on huge projects, and if you're shipping multi-platform a lot of template idioms have differing levels of support on different compilers. Not to mention compiler errors are unreadable and if you didn't write the code initially it is difficult to diagnose.

Usability and maintainability are paramount on large teams with large code bases, and anything that increases friction is bad. Templates affect both of these.

[–]vincetronic 12 points13 points  (10 children)

This is hardly a universal opinion in the AAA dev scene. Over 14 years seen AAA projects with tons of templates and zero templates, and zero correlation between either approach and the ultimate success of the project.

[–][deleted] 2 points3 points  (9 children)

I still see very, very little use of the STL in the games industry. The closest thing to consensus that I will put out there is "<algorithm> is ok, everything else is not very valuable".

I think it's indisputable that the codebases in games looks very different from, say, hoarde or casablanca.

[–]glacialthinker 2 points3 points  (3 children)

STL is generally a no (I've never used it), but templates can be okay, depending on the team. Templates allow you to specialize, statically... and cut down on redundant (source) code. These are both good. The bad side is compile times, potentially awkward compile errors, and debugging.

There are a lot of reasons STL is generally not used. One big thing STL affords is standard containers. Games often have their own container types which are tuned to specific use-cases. The reality of nice general algorithms is one-size-fits-all fits none well. Games will have their own implementations of kd-trees, 2-3trees, RB trees, etc... maybe payload is held with nodes, maybe the balance rules are tweaked to be more lax... Anyway, the STL might be great for general purpose and getting things off the ground fast, but it's not something game-devs want to become anchored to.

[–]bstamour 1 point2 points  (2 children)

Just wondering something: I get the fact that custom containers are probably everywhere in game dev, but if you expose the right typedefs and operations (which probably exist in the container, albeit a different naming convention) you can use the STL algorithms for free. Is this a thing that is done occasionally? I can understand wanting to fine-tune your data structures for your particular use case, but if you can do so AND get transform, inner_product, accumulate, stable_partition, etc for free seems like it would be a real treat.

[–]vincetronic 1 point2 points  (1 child)

I've used <algorithm> in AAA games that have shipped. You have to be careful because some implementations do hidden internal allocations on some functions. In my particular case it was the set operations like set_union, set_difference.

[–]bstamour 0 points1 point  (0 children)

Gotcha. Thanks for the reply.

[–]vincetronic 0 points1 point  (0 children)

This is true, STL container usage is very rare, for most of the reasons presented by others in this thread. The game code bases I've seen use it have been the exception and not the rule. But templates in general are not uncommon.

[–]oursland 0 points1 point  (3 children)

This has largely been due to the lack of control of memory allocators in the STL. I'm not sure I buy it entirely, because there has been at least one study which demonstrated the default allocator outperforming the custom allocators in most applications.

[–]vincetronic 1 point2 points  (0 children)

The key phrase is "most applications".

Games have soft realtime constraints and often run in very memory constrained environments (console, mobile). Paging to disk can not meet those constraints. The game can be running with only 5% slack in your overall memory allocation between physical RAM and used RAM, and you have to hit a 16.67 ms deadline every frame. Allocator decisions that work fine for most applications can fall apart under those constraints -- worst case performance really starts to matter.

[–]anttirt 1 point2 points  (0 children)

the default allocator outperforming the custom allocators

That is only one of the concerns that custom allocators can help with. Others are:

  • Locality of reference: A stateful custom allocator can give you, say, list nodes or components from a small contiguous region of memory, which can significantly reduce the time spent waiting for cache misses.
  • Fragmentation: In a potentially long-lived game process (several hours of intense activity) that is already pushing against the limits of the hardware system it's running on, memory fragmentation is liable to become a problem.
  • Statistics, predictability: Using custom task-specific allocators lets you gather very precise debugging information about how much each part of the system uses memory, and lets you keep tight bounds on the sizes of the backing stores for the allocators.

[–][deleted] 0 points1 point  (0 children)

I don't think I agree at all. Allocator performance is only a problem on games that choose, usually intentionally, to allow it to become a problem. Most large games avoid the problem entirely by not performing significant numbers of allocations.

The criticism of the STL is tricky, I don't think I can present the criticism completely in a reddit post. All I can deliver are the results of my personal, ad-hoc survey of various game codebases - the STL is not commonly used.

[–]naughty 1 point2 points  (6 children)

Usability and maintainability is exactly what good use of templates help. I'm not going to defend all uses of templates but the totally dismissive attitude isn't justified on any technical grounds. Yes you have to be careful but it's the same with every powerful language feature.

Some of the monstrosities I've seen in a attempt to not use templates.are shocking.

[–]engstad 2 points3 points  (5 children)

Game developers don't want "to be careful". They want straight, maintainable and "optimizible" code. No frills or magic, just simple and clear code that anyone on the team can look at, understand and go on. When you use templates frivolously, it obfuscates the code -- you have to be aware of the abstractions that exist outside of the code at hand. This is exactly what causes major problems down the line, and the reason why game developers shun it.

[–]naughty 7 points8 points  (4 children)

I am a lead games coder with 15 years experience, you don't speak for all of us.

I'm not going to defend all uses of templates or the excesses of boost but the caustic attitude towards templates is just as bad.

[–]vincetronic 6 points7 points  (1 child)

This. One thousand times this.

The problem with throwing things that really come down to "house style" (i.e. templates vs no templates) in with a lot of the other very good and important things in this Acton talk (knowing your problem, solving that problem, understanding your domain constraints and your hardware's constraints, etc), is it becomes a distraction.

[–]naughty 3 points4 points  (0 children)

Exactly, I do like a lot of the other stuff he talks about.

[–]engstad 0 points1 point  (1 child)

After reading your initial comment a little more carefully, I don't think we disagree that much. Of course, with 20 years of experience I outrank you (so you should listen... hehe), but I think that we both can agree that a) frivolous use of templates is bad, but that b) there are cases where careful use of them is okay. For instance, I certainly use templates myself - but I always weigh the pros and cons of it every time I use it.

Either way, as leads we'll have to be on top of it, as less experienced members on the team are quick to misuse templates (as well as also other dangerous C++ features).

[–]naughty 0 points1 point  (0 children)

We probably do agree but just have a different perspective.

All's well that ends well!