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
