[ENet-discuss] ENet performance (packet reuse/allocation, channel count...)
Kevin Gadd
kevin.gadd at gmail.com
Mon May 1 16:44:59 PDT 2006
Hey all,
I'm working on an experimental small-scale multiplayer engine that is
designed for fairly large (compared to a typical use of ENet, anyway) client
counts. Because of this, I'm going to be sending and recieving a LOT of data
(and packets). Currently, sending a packet to multiple peers requires
creating a copy of the packet for each individual peer (unless I'm sending
it to all my peers, and I can broadcast it). The expense of all these packet
allocations (and data copies) is somewhat significant. In general, having to
create a new packet every time I send data is complicating my network code
considerably. My previous performance tests of sending large amounts of data
via enet were not particularly encouraging - it worked, mostly, but the
library definitely struggled under heavy load, and completely failed if I
queued too many packets at once (due to what, I assume, is a fixed-size
queue somewhere). The limit on how many packets I could queue at once meant
I either had to batch packets in small amounts and service my host
repeatedly, or send very large packets. Large packets meant lots of big
copies and allocations, which wasn't much of an improvement either.
Is there a way I could reuse a single packet for multiple sends, or even
better, create a packet without allocating a new data block for it (ideally,
I'd be using an existing block of memory instead)? There doesn't seem to be
any straightforward way of doing the latter currently, but it seems like in
theory the former could work with the current ENet api at least (though none
of the documentation actually says whether or not a single packet can be
sent multiple times - the tutorial just says enet handles deallocating it
automatically).
If there isn't any good way of solving this problem with the current API,
I'd like to extend ENet to support setting up a custom allocator, or at
least passing pre-existing data when creating a packet. Either option would
allow me to easily pin my existing data in memory and pass it to enet,
saving a considerable number of allocations and copies. If this ends up
being the best route to take, any suggestions on how to design these changes
would be appreciated - if I go to the trouble of doing this, I'd like to
make sure and at least make the changes in a manner that allows them to be
integrated into the official codebase.
On a related note, I was also wondering if there is any significant
performance/memory usage impact involved in setting up a connection with
lots of channels. Ideally I can just set up all my connections with a good
number of channels (16, 32, 64, whatever), and start communicating on
different channels as needed without breaking client/server compatibility.
But if unused channels have a significant impact on performance I'll have to
wait until I really need the channels before I start using them.
In the meanwhile I'm going to keep mucking around and see what I come up
with, but I wanted to get some feedback from people that have more
experience with enet than I do.
Thanks,
-kg
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.cubik.org/pipermail/enet-discuss/attachments/20060501/e5741f4f/attachment.html
More information about the ENet-discuss
mailing list