-
Notifications
You must be signed in to change notification settings - Fork 5.1k
[Experiment] Reduce the number of syscalls #38747
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
Conversation
…ead does not peform a syscall but rather waits for epoll notification
…queue is empty, change the state to ready
This reverts commit 99ddeaf.
I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label. |
Tagging subscribers to this area: @dotnet/ncl |
…ects first non-blocking sync call
…e did not receive any new epoll notifications in the meantime (state==processing, _sequenceNumber++)
@geoffkizer I took your idea based on the following epoll man entry
and implemented a very simple version of it (see the files changed). After that, I've run the benchmarks for hardcoded version of SDK, Runtime and ASP.NET and aspnet/benchmarks git commit:
Against a locally built The results I got:
As you can see, the change improved the JSON benchmark throughput on Citrine and perf machines by almost +5%! It did not have such effect on AMD and ARM machines (my wild guess is that it's because they have more cores and we don't keep them 100% busy yet) The problem is, that I was not able to get all of the tests passing. Initially, I've run into two simple problems:
After fixing these two simple issues I was able to get the failing test pass locally: runtime/src/libraries/System.Net.Sockets/tests/FunctionalTests/NetworkStreamTest.cs Lines 644 to 659 in 1705e68
but the CI remained red. I've written a small app that basically put this test into a Based on the example of the test mentioned above. If we have pseudocode like this: server.Send(1024 bytes);
Console.WriteLine(client.Receive());
Console.WriteLine(client.Receive()); Most of the time the execution is as following:
The problem is that we not always receive two epoll notifications and sometimes end up waiting for
If I remember correctly you have suggested using an Another idea was to switch from edge to level-triggered I am open to any suggestions and ideas, but for now, I have to switch to some other 5.0 tasks and I am going to close this PR. It's hard to give up on this idea because with some other improvements that were recently merged, I am able to break the magic barrier of FWIW I was testing that on Ubuntu 18.04. |
@adamsitnik Thanks for the investigation here. I'll look at your code and see if I see anything. |
@adamsitnik What |
Here's a guess at what might be happening: If I understand your scenario correctly, what's happening is that the receiver has received all data, but hasn't received EOF yet, and is never getting an epoll notification that would trigger it to do another recv() and actually get the EOF. I suspect we are not handling EPOLLHUP notifications properly. That is, in rare cases the receiver has received both the data and the EOF from the sender before the epoll notification is triggered. epoll_wait returns something like EPOLLIN | EPOLLHUP for this socket. We call recv() and get a partially filled buffer, so we assume there's no more data to be read, but we also assume there will be another epoll_wait notification -- which apparently in this case isn't true. If we were to remember that we saw EPOLLHUP, then we would know that once we receive the partially filled buffer, then the client has sent EOF and no more data will be arriving. Note that as things are implemented currently, we don't ever rely on EPOLLHUP, since we always try to do the recv() and we'll always get EOF from this. But with this partial buffer optimization, we won't try to recv() until we get another epoll notification, which in this case will never happen. Thoughts? |
Yes, 1024.
Yes, exactly.
I am not familiar with the concept of |
Thanks, let me know what you find. BTW there's some weirdness with EPOLLHUP events here that we probably need to change:
|
Before I provide full benchmark results I want to get the status of tests from CI. Until then, please ignore this PR.