RFR: 8266369: (se) Add wepoll based Selector [v2]

Chris Hegarty chegar at openjdk.java.net
Wed May 5 09:43:58 UTC 2021


On Wed, 5 May 2021 07:09:16 GMT, Alan Bateman <alanb at openjdk.org> wrote:

>> This PR proposes a new Selector implementation for the Windows platform based on the Bert Belder's "wepoll" library. The wepoll library provides a scalable polling interface to the Ancillary Function Driver for Winsock. The interface that it exposes is close to the Linux epoll interface. The main benefit is that the cost of selection operations are a function of the number of sockets that are ready for I/O rather than the number of channels registered with the Selector. The existing Selector on Windows uses the legacy "select" which scales horribly, partly because it's O(N) on the number of registered channels and partly because it is limited to 1024 sockets and so requires a thread per 1024 sockets.
>> 
>> The patch brings the wepoll sources into the repo, adds a small shim, and the Selector implementation itself. The new implementation needs to handle OOB data in the same way as the old implementation so the method to discard OOB moves to Net.
>> 
>> I've added a microbenchmark to demonstrate the scaling when there is 1, 10, ... 10k connections and one socket ready for I/O. Windows Server 2019 was used for the data here. I've seen improvements with almost everything that I've tried. The only exception is a select after a wakeup where the old implementation skips the selection operation (arguably a long standing bug in the old implementation).
>> 
>> Existing select based Selector where the selection operation is almost 1ms when there are 10,000 channels registered.
>> 
>> Benchmark                (nchannels)  Mode  Cnt       Score       Error  Units
>> SelectOne.testSelectOne            1  avgt   20    1587.429 ±     4.053  ns/op
>> SelectOne.testSelectOne           10  avgt   20    2515.324 ±     8.141  ns/op
>> SelectOne.testSelectOne          100  avgt   20   10903.445 ±    65.508  ns/op
>> SelectOne.testSelectOne         1000  avgt   20  101651.369 ±   673.781  ns/op
>> SelectOne.testSelectOne        10000  avgt   20  932032.385 ± 59004.246  ns/op
>> 
>> 
>> New wepoll based Selector:
>> 
>> Benchmark                (nchannels)  Mode  Cnt     Score    Error  Units
>> SelectOne.testSelectOne            1  avgt   20  1428.914 ±  6.648  ns/op
>> SelectOne.testSelectOne           10  avgt   20  1429.806 ±  5.537  ns/op
>> SelectOne.testSelectOne          100  avgt   20  1433.371 ±  3.253  ns/op
>> SelectOne.testSelectOne         1000  avgt   20  1435.007 ± 12.420  ns/op
>> SelectOne.testSelectOne        10000  avgt   20  1445.201 ±  7.902  ns/op
>> 
>> 
>> Replacing the Selector implementation after 19 years of service is a big step. The proposal is to leave the existing implementation until there is confidence with the new implementation. It also serves as a backup in case Windows were to significantly change the AFD interface. The old Selector can be used by running with -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.WindowsSelectorProvider. A selection of existing tests have been updated to run a second time with the old Selector so that it is continues to be tested.
>> 
>> CSR and Release Note planned.
>
> Alan Bateman has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains six additional commits since the last revision:
> 
>  - Merge
>  - Propagate exception from discardOOB, cleanup
>  - Merge
>  - Use 'to' instead of '(int) timeout
>  - Move SelectorWakeup micro to channels directory
>  - Initial commit

src/java.base/share/classes/sun/nio/ch/Net.java line 685:

> 683:      * Read and discard urgent data (MSG_OOB) on the socket.
> 684:      */
> 685:     static native boolean discardOOB(FileDescriptor fd) throws IOException;

I see a native implementation of this method on Windows only, but it is in the shared `Net` class. This method is not called on non-Windows, but it it were there would be a problems ;-).  Was the intention to add other platform specific implementations, or to confine it to Windows only?

test/jdk/java/nio/channels/Selector/RacyDeregister.java line 47:

> 45:  * @run main/othervm/timeout=1200 -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.WindowsSelectorProvider RacyDeregister
> 46:  */
> 47: 

I like how this test can be run with the system property set for Windows only - nice!

test/micro/org/openjdk/bench/java/nio/channels/SelectOne.java line 80:

> 78:         ServerSocketChannel listener = ServerSocketChannel.open();
> 79:         listener.bind(new InetSocketAddress(0));
> 80:         SocketAddress remote = listener.getLocalAddress();

Maybe use a try-with-resources here so that the listener is closed.

-------------

PR: https://git.openjdk.java.net/jdk/pull/3816


More information about the nio-dev mailing list