Re: Optimal read buffer size?
Re: Optimal read buffer size?
- Subject: Re: Optimal read buffer size?
- From: Justin Walker <email@hidden>
- Date: Wed, 18 May 2005 12:53:35 -0700
On May 18, 2005, at 11:56, Chaz McGarvey wrote:
On May 18, 2005, at 12:35 PM, Justin Walker wrote:
On May 18, 2005, at 11:06, Chaz McGarvey wrote:
I find that when I write network code, I never really know how big I
should make the read buffer. Some protocols have only short packets
so I usually have a pretty small buffer, or only read in one packet
at a time, but if I'm reading in a very big packet like a
mult-megabyte resource download that I'm writing to disk, is there a
sweet spot that requires the fewest read calls and doesn't waste
(much) memory?
There is no such thing. First, your app doesn't worry about packets,
unless you are dealing with a datagram-based protocol (and generally,
those have limited packet size); and second, the kernel handles all
the buffering, and deals with it in a much different way than you do
in an application.
What are your concerns?
Sorry. I mean "packets" not in the TCP sense, but rather as a block
of information as defined by the high-level protocol. For example,
HTTP packets can get very large if the server is sending a big
resource.
Typically, these protocols deal with "streams", not packets or blocks
(FWIW).
I don't really know how the kernel handles sockets, but I have
assumed that it has its own limited buffer. My question involves
getting the data from the kernel into my own buffer so it can be
written to disk. I would want to do this as fast as possible, and it
seems like if my own application buffer was too small, I would be
calling the read function (probably recv as it were) more often than
is necessary. Likewise, the kernel can only return so much data
during one call (I think) so creating a buffer too big might just
waste memory. So I'm wondering if there is an optimal size.
The kernel buffering is limited, as you infer, and for TCP, you need it
for both inbound and outbound streams. You can, to an extent, control
this ("man setsockopt"; cf. SO_SNDBUF, SO_RCVBUF). If you have a good
idea of the data sizes ahead of time, you can increase the kernel
buffer space for your socket this way. Matching this to your app
buffering is probably a good thing as well.
One thing to keep in mind is that, since the transfer of data across a
network involves your host, the remote host, and a myriad of networking
gizmos in between, it's almost impossible for your app to do what you
want (w.r.to that global view). In fact, it's likely that the better
you do, the worse all others do, so you have to think about that while
designing your strategy (it's like the freeway: if everyone is trying
to jam their cars into that one space in front of you, and you aren't
letting anyone do that, all lanes grind to a halt).
Locally, I think the best you can do is to make the kernel socket
buffers reasonably large (but no larger :-}), and to match your
buffering to that of the kernel. And then be smart about how you
shuffle data between net and disk.
The upshot is that there is no sweet spot, but there are a number of
ways to improve efficiency. You won't be doing a great job the first
time you try; it takes practice. You've started out asking the right
kind of question.
Regards,
Justin
--
Justin C. Walker, Curmudgeon-At-Large
Institute for General Semantics
--------
When LuteFisk is outlawed,
Only outlaws will have LuteFisk
--------
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden