-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Drop unnecessary fields from SocketAsyncEventArgs #51078
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Drop unnecessary fields from SocketAsyncEventArgs #51078
Conversation
Tagging subscribers to this area: @dotnet/ncl Issue DetailsShrinks the size by one pointer
|
Isn't the pointer being passed to an overlapped I/O operation? How do we know it's not needed by the operation past the synchronous call? |
Docs specify it can be a stack pointer? https://docs.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_wsarecvmsg
|
|
747443b
to
a399559
Compare
Cool. Makes me a little sad it took us this long to figure that out, but thank you for doing so now :) |
src/libraries/Common/src/Interop/Windows/WinSock/Interop.WSARecv.cs
Outdated
Show resolved
Hide resolved
src/libraries/Common/src/Interop/Windows/WinSock/Interop.WSARecvFrom.cs
Outdated
Show resolved
Hide resolved
src/libraries/Common/src/Interop/Windows/WinSock/Interop.WSASend.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs
Outdated
Show resolved
Hide resolved
Was already doing it in once place: runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs Lines 400 to 406 in 9bb0427
|
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs
Outdated
Show resolved
Hide resolved
78e4825
to
8fa40a8
Compare
This is a very nice change. We should do the array pool change for linux as well when we bust the stack alloc limit |
src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs
Outdated
Show resolved
Hide resolved
Not entirely sure why the interface is not being set on the PacketInformation currently 🤔 |
src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/NetworkInterfaceBasicTest.cs
Outdated
Show resolved
Hide resolved
Some general thoughts here: First, doing stackalloc for WSABUF up to some limit for muti-buffer send/recv is goodness. And 16 seems like a reasonable limit. @tmds already made this change for Linux (though it's in a very different spot in the code) -- I think his limit was 8. Second, I'm a little wary of removing Maybe using ArrayPool here is a reasonable alternative, but I'm not sure. This seems like a case where ArrayPool reuse will be small and may be more trouble than it's worth. And if we are using ArrayPool, we need to be super confident we are not introducing any use-after-free issues. Third, another approach to shrinking SAEA would be to push some of its fields into "tear off" objects, particularly fields used by less common operations like ReceiveMessageFrom or SendPackets. The long-term plan here is to refactor SAEA in such a way that we can ensure individual operations only need to allocate the state they need. So some sort of tear-off model seems like a step in that direction. |
d0dd9f4
to
1f8e04f
Compare
Found the bug, unlike the |
The WSABuffer's only need to be fixed for the short duration of the submit call (they don't need to remain either valid, allocated or pinned waiting for the result); so maintaining a perminatly pinned buffer for potentially the lifetime of the app as soon as a multi-buffer call is made seems excessive, when they might be rare rather than frequent calls? That might make a case for a non-pinned array; however if you are making calls with more than 16 buffers is the rent and return from the ArrayPool going to be significant vs the IO time? The ArrayPool meaning the buffers are shared across all |
I think the fact that WSABufs only need to exist for the synchronous part of the send it's ideal usage of array pool and we get maximum sharing across multiple writes |
Looks like I broke something in my quick tidy up before pushing 😥 |
Ok, you convinced me. Let's kill |
@benaadams Where does this PR stand? |
I made a clean up on the stack allocation; but seem to be getting stack corruption now. However can't build anything in .NET6.0 in VS to look deeper currently dotnet/sdk#17461 |
@benaadams would it make sense to flip the PR to Draft until it is unblocked for further iterations? Thanks! |
Depend how long you think it will be till sdk unbreaks VS? 😅 |
No idea honestly. If you're blocked on it for more than a week, I think it is time to swap it to Draft and wait. It can be then easily swapped back ;) |
@benaadams looks like a week passed ... perhaps time to switch it to Draft until we can make it actionable? Thanks! |
1f8e04f
to
4710a54
Compare
Draft Pull Request was automatically closed for inactivity. Please let us know if you'd like to reopen it. |
Shrinks the size by 3 pointers on Windows (28 bytes)
Moving the 2 x
WSABuffer[]?
, 1 xbyte[]?
to stack rather than heap.