Sign in to follow this  

C++ : Struggling with design choice...using template/policies or object composition

This topic is 4483 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm preparing the base for a particle system, but not in the classic sense of gaming. The particle system is used to simulate physical behavior like diffusion (Einstein's Model, with a drift term) and eventually other physical phenomena. Each particle will carry properties and time-step according to a probability function in a 2d or 3d domain (eventually). Some of these properties will be a function of time. The particles will not 'die' in the classical sense of a gaming paradigm, they will instead leave the domain of interest at some point in time. At given steps a 'net' will be cast over regions of interest and the data will be accumulated for analysis. The number of particles could be anywhere from 10,000 to 1,000,000 or more. I'm struggling with a fundamental design decision...should I use templates/policies (static but fast and flexible) or should I use dynamic allocation with composition/aggregation (a bit slower, I've heard, but allows run-time allocation). Any suggestions or views on this would be appreciated. --random_thinker

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
as i'm currently also developing something along these lines (not particle related, though) i faced a similar problem (and to a degree i'm still facing it).

my general goals are very similar to yours; i needed a combination of extreme flexibility and speed (who doesn't, i know).

the problem is, yes templates, policies etc give you the best speed. but there might be situation where you don't know every parameter of your algorithms at compile time. say you're building a tool that lets you tweak the initial parameters to see what the effect will be. template policies are in their nature in contrast to the dynamic nature of an interactive tool.

the thing i wound up with in the end: both.

i started out with a completely template, policies driven design and then introduced versions with variable (run time) parameters. my experience was that if you achieve a very modular design in your policy based approach you won't have to copy&paste a lot of code. just the core structures need to be present twice. the algorithms doing the major work need to be independent of the implementation of the core datastructures i.e. make good use of (maybe homegrown) iterators.

i'm still working on details of my system, but everything's in place and the approach works very nice.
dynamic if you need it, but also compile-time template magic if the parameters are known and you're in it for the speed.

hope someone else can describe his/her experience with something like that. i don't think it's too uncomon in th library-writing crowd.

- simon

Share this post


Link to post
Share on other sites
Thanks and yes, I came across this method in some depth in 'C++ Templates' by Vandevoorde and Josuttus, with some array and vector classes that used policies and traits (which I think eventually led to the Blitz++ library). I've also looked at the Article in GameDev.net on 'Designing an Extensible Particle System using C++ and Templates' by Kent Lai, where he presents a very elegant solution to particle management.

However, this type of programming requires a LOT of thought or I would suspect that a coder could end up in a 'dead end alley' if not careful. What I don't want to do is make the wrong decision here and then have to spend weeks redoing the entire library. That's why I'm going to put some time into this before I go forward. I've just ordered 'Modern C++' to have a closer look at the use of traits and policies in templates. I suppose that part of my problem is that the development I'm doing is exploratory and the physics/math is evolving.

You seem to have combined both methods; did this happen by plan or by evolution?

--random_thinker

Edit: Again there are two arguments for exploratory nature of what I want to do: 1) static templates allow unbounded development, whereas 2) dynamic object composition is bounded. I suppose from this that a clear understanding of types should be known before bounded dynamic approaches are used.

Share this post


Link to post
Share on other sites
One of the problems with templates and policy/traints is debugging. It can be very difficult to track down where the bug is, because the compiler (g++ 3.3.5 at least) really bitches you out with template errors. From this perspective composition would be very much preferred.

--random_thinker

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
i combined both methods by design. i'm a little bit of a speed freak too, so i wanted to have the fastest method i could do - which lead me to using a template policy based design. on the other hand i know that especially for tools and easy (no compiler involed) configuration of the system you have to have access to some settings at run-time, too.
imo, those two goals are very much the negative of each other.
i would've liked to have only one solution for both ways of using the system, of course. but as i don't want to exclude the possibility of allowing compile-time template based optimizations i needed both methods.

as i said, that doesn't mean you have to double your code size (if that would happen i'd vote against my own idea). certain crucial parts of it have to be designed to accept either runtime, constructor parameters or template parameters. you can even hide most of this doubling from your own implementation using a combination of template specialization and stuff like boost::mpl to take the right 'branch' at compile time.

one thing, though: if you plan to mix, from my experience it is easier to have a system that's policy based and then make some aspects of it run time configurable. the policy based modular design will help you with that a lot. the opposite isn't recommended to much (this is more of a personal preference.. well.. the whole design is personal preference).

the thing is, that there will be the core data structures of your system that are a bit compilcated typedefs, maybe different forms of allocators etc...
however the majority of your code (especially since your library will feature a fair amount of physics computations) is without any trace of the underlying dual-method plumbing.

i think it's worth the effort, opening both worlds. from a pure engineering perspective (i.e. what this thing bring to the table in terms of milliseconds) it doesn#t give you as much as having a 16 byte aligned sse version, that employs some clever allocation scheme, for instance. you could build that into both methods, of course.

another take on it would be to look at the majority of use cases. if you never plan on having every/most parameters given at compile time, i'd go for composition. i would say that this might be the case in a games related project. if your focus is more on the physics simulation side i'd advocate the mixed version. i do think, however, that the composition based, run-time configurable version is essential as long as you want to modify your system outside the compiler.

(to understand my views a little bit better: the thing i'm working on is a genetic algorithm library that's targeted exclusively at real function minimization. that's where my goals of maximum compile-time and runtime configurability came from. btw, compile time specification of the inner workings of the algorithm have turned out to be the most valuable thing in the library. that's something you don't get so nicely without polices.)

best regards,
- simon



Share this post


Link to post
Share on other sites
Guest Anonymous Poster
read the article on gamedev you mentioned which is really a good example of policy based design. it also illustrates that from there you wouldn't have a long way towards making the system configurable at runtime to the extent you need.
the mixture of specifying behaviour at compile time and data parameters at run time is its strength.

- simon

Share this post


Link to post
Share on other sites
Thanks Simon,

I guess that a combination is the best approach. This way you can use C++ where it is best suited for the problem at hand. When you think about it, the C++ Std Library is really a combination of unbounded static templates and bounded dynamic C++ classes (like the string library).

Also, I like your suggestion to make the basic infrastructure of policy-based templates and then add on dynamic features. But I'll really have to think this through carefully now.

Share this post


Link to post
Share on other sites
Always be sure to try to use the right tool for the job. And "do the simplest thing that could possibly work". The amazing thing is how easy it is to disagree - with others and with oneself - about what approach is "simplest".

Templates are static, fast and smaller at runtime (in terms of the data layout for objects; the code is normally larger). They are not "more flexible"; that's opposed to "static". The whole idea with composition is that you can change what's composed at runtime.

If you're naturally good with templates, you may find it easy to do everything by policies (except where you "know" that you'll need the extra options), and consider it the simplest thing. I think most sane people and/or those from an OO background will consider composition to be more intuitive in the general case, and policies to be a (somewhat deeply magical) form of optimization.

It would help to know what exactly you propose to do with the composed objects or policies; i.e. what a particle will logically contain (when you use policy classes it *is* a form of aggregation; you're just making use of the fact that the aggregated thing is constant, and thus of constant type, in order to exploit the cheap vtable dispath. The data still appears in your object's layout - as one of the bases instead of as a member).

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
yep. nothing wrong about that approach. sometimes i have the feeling that template policy madness is all the hype now among the library writing crowd (to question my own decision a little). i do believe in the principles of it but i also agree that it's easier to get your head around the composition based approach; maybe that's because the language lends itself more to this, as you said. maybe it's more natural for us because of this. i can understand the reasons you chose composition.
i 'd like to suggest to design the algorithms with both the policy way and the composition way in mind. if you're not satisfied with the way you started out for some reason make sure you can use the majority of the algorithms with as little change as possible when using the other approach i.e. abstract (template based abstraction) to a rather fine level.

i hope you're doing well with designing and implementing your system, random_thinker. you're in the fun stage of envisioning the design (i'm always the happiest when in that phase :) but then.. i'm modern c++ addicted +g+

maybe you can post a short comment how things are going. i'm very much interested in modern design questions like this one, so i'm watching this thread :)

regards
- simon

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Templates are static, fast and smaller at runtime (in terms of the data layout for objects; the code is normally larger). They are not "more flexible"; that's opposed to "static". The whole idea with composition is that you can change what's composed at runtime.


I suppose that I've not used the word 'flexible' appropriately. I was using in the context of templates being type unbounded, rather than as a runtime issue. And Kent Lai's article does illustrate real flexibility of design by introducing new policies governing particle behaviour. Templates do not come naturally to me, that's for sure, they are like a meta-language, where you almost have to think like a compiler would, in some cases (I'm studying 'C++ Templates', Traits and Policies Classes, and this can be a steep learning experience at times). But I cannot deny the awesome power that they can provide when needed. Just look at the simple 'lexical_cast<>', what elegance!. And Kent Lai's article on their use for particles is a real eye-opener.

I presently sprinkle my oo code with templates now, where needed. But introduciong policy-based templates->patterns will be a major shift in design approach. In fact, studying this concept is making me rethink the programme that I've done to date, and I've realized that there are already some 'patterns' lurking there, waiting to be addressed in a better way.

One thing that I've noted about C++ programming, the more that I learn it, the smaller the code gets. My code keeps shrinking and shrinking as it develops.

--random_thinker

Share this post


Link to post
Share on other sites

This topic is 4483 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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