Memory pool when receiving network messages
Hi
My question is how to manage memory when packets new network packets arrives. I''ve a ''big'' buffer where a recvfrom() it and copy it in a new *char[], and once the data are processed delete[] it. I think it would be a BIG bottleneck and will fragment the memory.
Does some one have an idea ?
- Iliak -
- Iliak -
[ ArcEngine: An open source .Net gaming framework ]
[ Dungeon Eye: An open source remake of Eye of the Beholder II ]
[ ArcEngine: An open source .Net gaming framework ]
[ Dungeon Eye: An open source remake of Eye of the Beholder II ]
If you know that your messages will never be large than some maximum size, you chould just have a buffer preallocated that you reuse. A variation along this line would be to use a circular buffer so that you only have to change index values to "delete" data.
MJB
MJB
Some operating systems and/or runtime libraries have specific facilities to create separate heaps. For example, HeapCreate() on Windows. By using a separate heap you can control fragmentation and reduce contention on any locks held by the heaps.
Alternately there are any number of pooled memory allocators that you can find online or in intermediate level C++ books that you can use to create your own allocator.
Another possibility is to use something like a static std::vector, and just leave the memory floating around between calls. If the buffer needs to be expanded for whatever reason, it''s a single call.
Alternately there are any number of pooled memory allocators that you can find online or in intermediate level C++ books that you can use to create your own allocator.
Another possibility is to use something like a static std::vector, and just leave the memory floating around between calls. If the buffer needs to be expanded for whatever reason, it''s a single call.
You absolutely want to pre-create and re-cycle your networking buffers. If someone sends you a packet bigger than your protocol''s biggest packet, then they''re spoofing you, and you''re safe to drop the packet.
Allocate a bunch of packets up front (or a ring buffer) and re-use those throughout the program.
Allocate a bunch of packets up front (or a ring buffer) and re-use those throughout the program.
enum Bool { True, False, FileNotFound };
Why even keep more than one packet buffer around, ever?
read packet
process packet
read packet
process packet
no copy, no buffer management.
This assumes that you are polling a non-blocking network socket and doing all the processing on that thread. Which in a game situation is almost always the simplest/best way to do it.
read packet
process packet
read packet
process packet
no copy, no buffer management.
This assumes that you are polling a non-blocking network socket and doing all the processing on that thread. Which in a game situation is almost always the simplest/best way to do it.
It sound a good idea, but... (there''s always a ''but'' around) i''m using 4 threads....
- Iliak -
- Iliak -
- Iliak -
[ ArcEngine: An open source .Net gaming framework ]
[ Dungeon Eye: An open source remake of Eye of the Beholder II ]
[ ArcEngine: An open source .Net gaming framework ]
[ Dungeon Eye: An open source remake of Eye of the Beholder II ]
A single receive buffer is possible, but I''m assuming you''re going to want to manage your send buffers using the same code. And because you''ll want to coalesce outgoing messages to the same destination so that you don''t send too many packets, this means that you need some kind of packet management.
Four threads is probably too much. You should start with no threads at all, and only add threads if:
1) You need asynchronous operation, and the API does not give you asynchronous behavior (i e, file I/O on DOS-based Windows).
2) You can PROVE that multiple threads will improve performance. As a first requirement, this means dual CPUs, but you also need to make sure that one thread is compute bound when the other is memory bound, and the cost of the synchronization overhead needs to be less than the gains.
Usually, 2) isn''t actually ever true (except for scientific computation and the like) so 1) is the typical case to use threads.
Four threads is probably too much. You should start with no threads at all, and only add threads if:
1) You need asynchronous operation, and the API does not give you asynchronous behavior (i e, file I/O on DOS-based Windows).
2) You can PROVE that multiple threads will improve performance. As a first requirement, this means dual CPUs, but you also need to make sure that one thread is compute bound when the other is memory bound, and the cost of the synchronization overhead needs to be less than the gains.
Usually, 2) isn''t actually ever true (except for scientific computation and the like) so 1) is the typical case to use threads.
enum Bool { True, False, FileNotFound };
I use threads like this:
1 for receiving messages
1 for sending messages
1 for processing messages and client/server mode
1 for scheduling task
maybe it's too much. I'll see with the profiler once everything is done...
If you can read french, I've done a .pdf that explain everything i want to do at ftp://iliak.dyndns.org/NetEngine/NetEngine.pdf login:anonymous pwd:toto@toto.com
- Iliak -
[edited by - iliak on May 3, 2004 10:30:24 AM]
1 for receiving messages
1 for sending messages
1 for processing messages and client/server mode
1 for scheduling task
maybe it's too much. I'll see with the profiler once everything is done...
If you can read french, I've done a .pdf that explain everything i want to do at ftp://iliak.dyndns.org/NetEngine/NetEngine.pdf login:anonymous pwd:toto@toto.com
- Iliak -
[edited by - iliak on May 3, 2004 10:30:24 AM]
- Iliak -
[ ArcEngine: An open source .Net gaming framework ]
[ Dungeon Eye: An open source remake of Eye of the Beholder II ]
[ ArcEngine: An open source .Net gaming framework ]
[ Dungeon Eye: An open source remake of Eye of the Beholder II ]
it thinkl it was in the enginuity (or whatever) tutorial, somewhere round the gamedev.net, where the autor wrote his idea of a ringbuffer. you ave i.e. a fixed size array, in which you save your input. the current location of the last input in the array is stored in an integer. then you have the position in the array to next read from. everytime you read or write, the specific integer is incremented. this could look like this:
edit:
this is the most simplest implementation. remember to pick your size big enough with this, because else, your netcode could flood your ringbuffer, overwriting old but not handled input.
[edited by - fooman on May 3, 2004 11:07:32 AM]
[edited by - fooman on May 3, 2004 4:38:05 PM]
edit: the final source is available some posts below...
edit:
this is the most simplest implementation. remember to pick your size big enough with this, because else, your netcode could flood your ringbuffer, overwriting old but not handled input.
[edited by - fooman on May 3, 2004 11:07:32 AM]
[edited by - fooman on May 3, 2004 4:38:05 PM]
When using multiple threads, you are going to need to do some type of resource control on the ring buffer. You don''t want two threads modifying the ring buffer at the same time.
I agree about using multiple threads. Have the networking part separate and just throw the packets into a buffer that is processed by the main thread.
- onebeer
I agree about using multiple threads. Have the networking part separate and just throw the packets into a buffer that is processed by the main thread.
- onebeer
- onebeer
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement