Doesn't the capture just refer to the WSABUF structures themselves, and
not the buffers they describe?

While it has been about 10 years since I wrote network device drivers
for a living, back then it was very definitely the case that network
cards would work directly with user buffers. (It was technically
possible to create a driver that made a copy, and some very simple and
cheap network cards might require that. But this was best avoided as the
perf tends to be really bad when you do that.)

So I'd be very surprised if the actual buffers themselves are being
copied. I'm pretty sure you'll find it's just the WSABUF structures that
are copied. (And they might not actually be copied as such - it's just
that the service provider needs to retain all the information they
contain. It might do this by incorporating that data into its internal
data structures rather than copying the WSABUFs themselves.)


By the way, there was some talk of cache locality of reference earlier.
One thing worth bearing in mind is that network transmit and receive
operations will end up flushing the relevant buffers out of cache
anyway. In order for the network card to be able to transmit the
contents of a buffer, those contents need to have been written out to
main memory - your network card can't see inside your CPU cache! And
when a receive occurs, the driver has to inform the OS memory manager
that the contents of the buffer have just been modified and that any
cached data held by the CPU is now out of date.

So you might not see much benefit from locality of reference here.

(Although there's one case you might: if a buffer that's just been used
for a read is then recycled for a write, then depending on the access
patterns used to write the data, that might reduce the cache chatter a
little. Also, if your buffer pool is large enough you might be able to
reduce working set size under low load by using a stack. So it might
still be worth it. But be prepared for relatively disappointing
results...)


-- 
Ian Griffiths



-----Original Message-----
From: Peter Ritchie
Sent: 10 August 2006 10:07

Greg, I meant to chime in on this earlier...  I'm currently waiting for
further clarification of documentation from Microsoft for WSASend[To]
(which is eventually used by Socket.BeginSend).  What I've gotten from
Microsoft so far is that the memory given to WSASend, when asynchronous
(overlapped I/O), is copied (referred to as "capture" in the WSASend
documentation) before being returned from WSASend.  As far as I can
tell, Socket.BeginSend also makes a copy of the memory it's asked to
send, pins it, then gives it to WSASend.  If what I'm hearing from MS
abount WSASend and the "service provider's responsibility to capture
[the buffer] ...
before returning from [the call to WSASend]" is true, it seems redundant
to copy these buffers and pin the copies if the buffer need only exist
for the duration of the WSASend call--unless they know something they're
not willing to tell.  I was under the impression that memory assigned to
a reference can't move while it's being used in a method call,
especially a PInvoked call.  Although it would be fairly trivial to test
if the above is false (but wouldn't be conclusive if not proven to be
false), I haven't.

I don't know if your focus is mainly receive rather than send; but, I
thought the above might be of interest...

On Tue, 1 Aug 2006 17:15:47 -0400, gregory young
<[EMAIL PROTECTED]>
wrote:

>Ok so I think everyone can agree that creating buffers on the fly in an

>async socket server is bad ... there is alot of literature available on

>the problems this will cause with the heap. I am looking at a few 
>options to get around this.
>
>1) Have a BufferPool class that hands out ArraySegment<byte> portions 
>of a larger array (large enough that it would be in the LOH). If all of

>the array is used create another big segment.
>
>2) Create a bunch of smaller arrays for use by the bufferpool class and

>have it hand them back
>
>In both 1 & 2 I would probably have the connection use their buffer for

>the duration of the connection. I would internally hold a list of the 
>free blocks. When a connection was done ith its buffer it would have to

>release it back to this pool. My thought is that #2 might be better for

>dealing with cases where I want to shrink the number of buffers 
>allocated from the previous maximum if needed.
>
>In general I lean towards #1 ... but figured I would check if I might 
>be missing something.

===================================
This list is hosted by DevelopMentor®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to