Boost logo

Boost :

Subject: Re: [boost] [mixin] New library reminder
From: Klaim - Joël Lamotte (mjklaim_at_[hidden])
Date: 2013-07-13 07:46:20


On Sat, Jul 13, 2013 at 1:11 PM, Borislav Stanimirov <b.stanimirov_at_[hidden]>wrote:

>
> Which then would allow something like:
>>
>> world_components.for_all<book_**data>( [&]( book_data& data ){
>> data.update(
>> info ); } ); // go through the array of book_data to update them all
>>
>>
> I'm not sure what this is supposed to do. You could do something like
>
> for(auto o : objects_with_book_data) // your own array
> {
> o->get<book_data>()->update(**info);
> }
>
> You could also have a message called update (handled by not necessarily
> only book_data) and code:
>
> for(auto o : objects)
> {
> update(o, info);
>
> }
>
>
It's the same semantically but not on the performance side.
Also it prevent being able to update the unrelated components in parallel.

In most component system in game engines, all the components of the same
types are defined in a kind of array to allow
updating these components with one loop per component type, each update
loop being dispatched to a thread pool as a concurrent task.

Basically what I say is that your setup works and is nice and works in most
contexts, so really I'm talking about optimization opportunities.
The thing is this:

for(auto o : objects_with_book_data) // your own array
{
    o->get<book_data>()->update(**info);
}

Might jump around memory in unpredictable order depending on book_data
instances location in memory, which depends on how you allocated it.
It's a problem only when you need high performance and high count of mixin
objects and components, so it's not usual, but it's usual in game engines
(and I suspect it is usual too in other high performance software - because
of the opportunity to avoid cache misses - in particular on ARM, basically
any high performance mobile application).

> What I fear is that the allocator would not be enough to allow different
>> pool/list/whatever of these components to be defined,
>> for different "contexts". I have a case where I need different "worlds" to
>> exists in parallel and components are gathered in type-specific (stable)
>> arrays.
>>
>>
> The allocator works like this.
>
> When an object is created or mutated it first allocates the array of mixin
> pointers for its mixins, then it allocates memory for each new mixin (plus
> object*) and arranges them in this array.
>
> You're allowed to set a global allocator that takes care for all these
> allocations, and you're also allowed to assign specific allocators per
> mixin type. For example book_data_allocator, which will take care to
> allocate memory only for mixins of type book_data.
>
> So if your programs often mutates a huge group of objects by adding and
> removing specific mixin to them it's a good idea to provide a specific
> allocator for that mixin type and pre-allocate the entire chunk memory.
>
>
That's what I understand, but my question was relative to the case where
you don't want all the components to be allocated in the same memory
container (pool/array/stable_vector, whatever).
To make to make it clearer: are allocators allowed to have a state, in your
library?

Because it needs to know in which "world" pool to allocate. This assume
that the different worlds are potentially not updated in the same thread or
at the same time (which happen a lot in client/server systems).
Also it allow updating only the world you want to update when it is acive,
while keeping all the differnt worlds in memory - reducing efforts updates
when the "player" in a game can be in only one world at a time.
Basically, if I have to allocate, say, all the physics components in the
same global array, then I'll have a hard time updating only those that
correspond to a specific world, because if there is a lot of worlds
and a lot of physics objects, I'll have to go through all of them just to
update those of one world.

If I can set dynamically the allocator object, then that indeed solves all
I mentionned.

> As for your worlds example you could easily set the allocator to all
> rendering mixins to be A, and to all physics mixins to be B.
>
>
I don't understand this sentence. Do you mean different allocators per
type? If yes then that's what I understood already but not what I'm asking
for, as already described.

In any way, that is for both optimization and flexibility of use that I'm
asking that, the library is currently already very interesting.
Most games don't have more than one world running in memory at the same time
and not all games have tons of elements to update quickly and not all games
have to run on ARM efficiently.
It just appears that mines does. :D

Joel Lamotte


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk