# Messages and dynamic memory

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

## Recommended Posts

Hi.

I am wondering about this. Is there a good way to do event messages between two large-scale loose-coupled parts of a game program without having to dynamically allocate and deallocate the messages? Messages may need to be queued, and there can be different types of messages, which suggests an inheritance hierarchy and that's where the dynamic memory stuff comes from, at least when using C++ as I'd be in this case. Thanks.

##### Share on other sites

Well you can send different size messages if theyre prefixed with a size or type.

Like serialize size followed by data (probably the raw memory) in a queue of bytes, and on the other end read the object into contiguous memory (since std::queue is not contiguous) and interpret the address as a Base*.

But unless you actually need something like that for performance reasons, I wouldnt do it because it seems a bit prone to bugs. Maybe if you do proper serialization instead of raw memcpy (or use POD types + switch instead of inheritance) its safer... (does c++ even allow raw memory copy of objects with virtuals?)

##### Share on other sites

Well you can send different size messages if theyre prefixed with a size or type.

Like serialize size followed by data (probably the raw memory) in a queue of bytes, and on the other end read the object into contiguous memory (since std::queue is not contiguous) and interpret the address as a Base*.

But unless you actually need something like that for performance reasons, I wouldnt do it because it seems a bit prone to bugs. Maybe if you do proper serialization instead of raw memcpy (or use POD types + switch instead of inheritance) its safer... (does c++ even allow raw memory copy of objects with virtuals?)

Why would we serialize messages? This is about internal communication within the program.

##### Share on other sites

Assuming there's a fairly limited number of different message classes with a high number of instances over time, object pooling might be a good choice. Allocate once, and instead of deallocating, free them to a pool from which you later get them once needed. It will never run out of messages and never allocate more money than needed.

##### Share on other sites

Why would we serialize messages? This is about internal communication within the program.

Because it provides one solution to your problem. You can allocate a single block of memory and messages and write themselves into the buffer, etc...

First, I'd make sure you really need a messaging system anyway. Ideally you could replace them with method calls, and that would make the dependencies more clear.

If you really do need some sort of message-like design though (for instance, to be able to queue up messages and process them later), then ask yourself if dynamic allocation will really be a problem (I assume you're worried about performance of dynamic allocation).

##### Share on other sites

Are you developing for mobile? As Phil said, I dont think the overhead of alloc/dealloc will be significant unless you literally create/destroy thousands of messages each frame and have a limited processing power. Don't over-optimize before you have to.

That being said, pooling is probably your first step solution for any alloc/dealloc optimizations. You can also stick to simple strings/enum/cachec const vars instead of a messaging class and pass the params as (templeted) function parameters rather than in the message object itself.

##### Share on other sites

Why would we serialize messages? This is about internal communication within the program.

Because it provides one solution to your problem. You can allocate a single block of memory and messages and write themselves into the buffer, etc...

First, I'd make sure you really need a messaging system anyway. Ideally you could replace them with method calls, and that would make the dependencies more clear.

If you really do need some sort of message-like design though (for instance, to be able to queue up messages and process them later), then ask yourself if dynamic allocation will really be a problem (I assume you're worried about performance of dynamic allocation).

Yes, I suppose that you could just use method calls, e.g. inherit from some kind of interface class which is kept suitably loose that implementation details don't leak, but then you can't defer processing until later, which was the purpose of the messaging system.

##### Share on other sites

I am wondering about this. Is there a good way to do event messages between two large-scale loose-coupled parts of a game program without having to dynamically allocate and deallocate the messages? Messages may need to be queued, and there can be different types of messages, which suggests an inheritance hierarchy and that's where the dynamic memory stuff comes from, at least when using C++ as I'd be in this case. Thanks.

Big bloated generic "event" systems are overkill. Write something specific.
e.g. Producer and Consumer are decoupled, but an application wants one to forward an event to the other:
class Producer
{
public:
Producer( const std::function<void(int)>& onFrobnicate )
: onFrobnicate(onFrobnicate)
, foo() {}

void Frobnicate()
{
onFrobnicate(foo++);
}
private:
std::function<void(int)> onFrobnicate;
int foo;
};
class Consumer
{
public:
Consumer() : foo() {}
void Foo( int x )
{
foo += x;
}
private:
int foo;
};
class Application1
{
public:
Application1()
: producer(std::bind( &Consumer::Foo, consumer, _1 ))
{
for( int i=0; i!=10; ++i )
producer.Frobnicate(); // calls consumer.Foo 10 times
}
private:
Consumer consumer;
Producer producer;
}
Or if the application wants to buffer the events:
class Application2
{
public:
Application2()
: producer([&](int x){events.push_back(x);})
{
//we expect to buffer 10 events, so let's pre-allocate that much memory as an optimization:
events.reserve(10);

for( int i=0; i!=10; ++i )
producer.Frobnicate(); // pushes 10 results into 'events'

//now send the buffered events to the consumer:
for(auto i: events)
consumer.Foo(i);
events.clear();
}
private:
Consumer consumer;
Producer producer;
std::vector<int> events;
}
Isn't that easier than using some big inheritance-based messaging framework? C++ has tools for this already

To answer the other question -- if you did need to dynamically create a big stack of temporary messages, I'd use a pool allocator, or even better, a stack allocator. Stack allocators are the cheapest possible allocation of any algorithm, and are built around bulk destruction (freeing every allocation made at the same time).
In the above code, the vector acts like a stack allocator, which is a good start, and could be optimized further by replacing it with a hand-coded/optimized stack allocator.

##### Share on other sites

Seconding Hodgman, I honestly consider "big hub" message exchange architectures lack of proper design. I don't recall a single case which, on closer scrutiny really required the arbitrary mappings.

While I support the notion above I would rather stay away from std::bind. To be honest I would go with an explicit 'onIntGenerated' callback or 'onIntListener' interface.

Edited by Krohm

• 37
• 12
• 10
• 10
• 9
• ### Forum Statistics

• Total Topics
631360
• Total Posts
2999554
×