Comparing Java 7 Async NIO with NIO.

Overview

SDP (Sockets Direct Protocol) in Java 7 promises better integration with InfiniBand. This comes with a new Socket classes AsynchronousSocketChannel and AsynchronousServerSocketChannel. Is there any advantage in using these libraries if you don't have InfiniBand?

Creating a server socket

The API for AsynchronousServerSocketChannel is slightly different to ServerSocketChannel. The most notable difference is the use of Futures instead of always blocking.
final AsynchronousServerSocketChannel ssc =
      AsynchronousServerSocketChannel.open().bind(new InetSocketAddress("localhost", 9999));
Future<AsynchronousSocketChannel> accepted = ssc.accept();
AsynchronousSocketChannel sc2 = accepted.get();

ByteBuffer bb = ByteBuffer.allocateDirect(4096);
Future<Integer> readFuture = sc2.read(bb);

Creating a client socket

Similarly the client can start a connection and later wait when the connection is really needed.
AsynchronousSocketChannel sc = AsynchronousSocketChannel.open();
Future connected = sc.connect(new InetSocketAddress("localhost", 9999));
// later ensure we are connected.
connected.get();

ByteBuffer bb = ByteBuffer.allocateDirect(4096);
// populate bb
Future<Integer> writeFuture = sc2.write(bb);

Is there any performance differences?

Without threads, the Asynchronous IO was 5-10% faster. However once threads were used, the performance dropped. This could be because this is Java 7 update 0. I look forward to testing this again in the future.


Async Socket latency was 1/50/99%tile 5.2/5.4/7.3 us
Async Socket Throughput was 186 K/s
Threaded Async Socket Latency for 1/50/99%tile 13.8/16.9/24.7 us
Threaded Async Socket Throughput was 183 K/s
The best of three runs was used.

For comparison, the same tests using regular NIO on Java 7 were
Socket latency was 1/50/99%tile 5.6/5.8/7.0 us
Socket Throughput was 170 K/s
Threaded Socket Latency for 1/50/99%tile 6.0/8.5/10.7 us
Threaded Socket Throughput was 234 K/s

The code

Its worth nothing that the code is slightly more complex to use than regular NIO. However, the features added are powerful and for the brave, it will be valuable.

Asynchronous NIO Socket - AsyncPingTest.java

Plain NIO Socket - PingTest.java

Conclusion

The API for Asynchronous sockets looks promising despite the added complexity. However the performance many not be there unless you have the right hardware, yet.

Comments

  1. Myeah well, there is no use for async sockets as long as the logic in the thread is linear:
    * send request
    * read response, because response is needed for the next step
    * do something with response
    * send another request that uses part of response
    ...

    But if the network request/responses can be parallelized because you need to make several requests to different peers that are not interdependent (the requests, not the peers ^^), then there might be a big advantage with async sockets, because you don't need to jump through the hoops of having a thread pool to do so.
    Not that it's complex but, well, it's even more threads...

    But that would only make sense with something alike the CompletionService for the async sockets:
    http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CompletionService.html

    ReplyDelete
  2. @loki, The comparison is with non-blocking NIO which doesn't wait to send data either. With NIO the transfer with the ByteBuffer is synchronous, with asynch IO the transfer can be occurring in parallel. It should be faster in low latency situations.

    You can service almost any number of non-blocking NIO connections with one or a few threads.

    ReplyDelete
  3. @loki, I still think the latency test is valid. You will get the lowest latency when you have only one request at a time.

    However for a throughput test, you want many concurrency requests. I will change the test to see if increasing the number of concurrent requests, and/or increasing the number of connections helps throughput.

    ReplyDelete
  4. This is Paul Krill of InfoWorld. I am looking for Java developers to give me their impressions of Java SE 7. Anyone who wishes to participate, please email me at paul_krill@infoworld.com. Thanks!

    ReplyDelete
  5. Mr. Lawrey, could you contact me at my email address? paul_krill@infoworld.com

    ReplyDelete
  6. The latency test means nothing. The latency of your test code will only depend on I/O hardware, not I/O model.

    ReplyDelete
  7. @Atry, Can you clarify what you mean? Can you explain the differences given the hardware is the same?

    ReplyDelete
  8. What is the influence of selectors to NIO? As I can see client sockets in the test are in blocking mode.

    ReplyDelete
  9. Since each connection has its own thread(s) I didn't bother with Selectors. I would expect these to have a small performance hit in this case. Selectors make sense which you are concerned about scalability so another test with many connections would be interesting.

    ReplyDelete

Post a Comment

Popular posts from this blog

Low Latency Microservices, A Retrospective

Unusual Java: StackTrace Extends Throwable

System wide unique nanosecond timestamps