August 2012 Archives

Continuing my analysis of the performance of the new Winsock Registered I/O API, RIO, compared to more traditional networking APIs we finally get to the point where we compare I/O completion port designs.

I've been looking at the Windows 8 Registered I/O Networking Extensions since October when they first made an appearance as part of the Windows 8 Developer Preview, though lately most of my testing has been using Windows Server 2012 RC. Whilst exploring and understanding the new API I spent some time putting together some simple UDP servers using the various notification styles that RIO provides. I then put together some equally simple UDP servers using the "traditional" APIs so that I could compare performance. It took a pair of 10 Gigabit network cards to fully appreciate the performance advantages of using RIO with the simpler server designs and now I can present my findings for the more complex server designs.
This article presents the sixth in my series of example servers for comparing the performance of the Winsock Registered I/O Networking extensions, RIO, and traditional Windows networking APIs. This example server is a traditional multi-threaded, IOCP based, UDP design that we can use to compare to the multi-threaded RIO IOCP UDP example server. I've been looking at the Winsock Registered I/O Networking Extensions since October when they first made an appearance as part of the Windows 8 Developer Preview, though lately most of my testing has been using Windows Server 2012 RC. Whilst exploring and understanding the new API I spent some time putting together some simple UDP servers using the various notification styles that RIO provides. I then put together some equally simple UDP servers using the "traditional" APIs so that I could compare performance. This series of blog posts describes each of the example servers in turn. You can find an index to all of the articles about the Winsock Registered I/O example servers here.
There's an interesting question over on stack overflow about a perceived change in IOCP behaviour on Windows 8 (and Server 2012 RC).

The question includes some code which demonstrates how an overlapped AcceptEx() call is blocked on by the thread that issued it being blocked inside a call to ReadFile() at the time that the AcceptEx() completes. The completion for the AcceptEx() is delayed until the ReadFile() completes even though a thread is waiting for completions on the IOCP associated with the socket. The "delaying" behaviour only shows up on Windows 8 and Windows Server 2012 RC. On all other platforms everything works "as expected" and the fact that the thread that issued the AcceptEx() has blocked in no way affects the completion of the accept.

I can't see anything wrong with the example code (and I've also tested with code which loads AcceptEx() "correctly" using WSAIoctl(), but I may be missing something... I can reproduce the issue here and I can confirm that the problem does not affect WSARecv() calls (that is, I changed the example to use WSAAccept() to accept the connection in a blocking manner and then issue an overlapped WSARecv() before entering the blocking ReadFile() and everything works as expected.

This is a slightly worrying change for those of us using AcceptEx() from arbitrary threads! I've yet to check to see if the stalled accept completion blocks the head of the IOCP and stalls ALL subsequent completions on the IOCP or if it is simply blocking the accept completion...

With The Server Framework you could switch to disabling JETBYTE_STREAM_SOCKETS_SKIP_MARSHAL_TO_IO_POOL and force all I/O to be done by one of the I/O threads. Assuming you perform no blocking calls on your I/O threads then you would be fine.

I expect I'll add a further option which will let you forcibly marshal just AcceptEx requests to the I/O pool when running on Windows 8/Server 2012... Unfortunately existing code which uses AcceptEx and is compiled with JETBYTE_STREAM_SOCKETS_SKIP_MARSHAL_TO_IO_POOL enabled could fall foul of this rather strange change in the underlying operating system.

Hopefully this is a bug which will get fixed pretty quickly!
I've been looking at the Windows 8 Registered I/O Networking Extensions since October when they first made an appearance as part of the Windows 8 Developer Preview. Whilst exploring and understanding the new API I spent some time putting together some simple UDP servers using the various notification styles that RIO provides. I then put together some equally simple UDP servers using the "traditional" APIs so that I could compare performance.

I had my first attempt at performance comparisons back in March and whilst the results were in RIO's favour they weren't especially compelling given the new API you needed to learn and the fact that the resulting code would only run on Windows 8/Server 2012 and later. As I moved on from the simplest servers to more complex ones it became increasingly difficult to justify the code change for the performance improvement. I began to doubt my test environment and so upgraded the networking from teamed 1Gb connections to a pair of Intel 10 Gigabit AT2 cards wired back to back. It then became apparent that whilst my test server was fine in this configuration, I didn't have another machine that was powerful enough to do the networking justice... After adding another new machine to the test system I could finally drive the 10 Gigabit AT2 cards at full capacity and having just begun to run the original tests again I can now clearly see the advantage of using RIO.

Do bear in mind that I'm learning as I go here, RIO is a new API and there is precious little in the way of documentation about how and why to use the API. Comments and suggestions are more than welcome, feel free to put me straight if I've made some mistakes, and submit code to help make these examples better.

Latest release of The Server Framework: 6.5.7

| 0 Comments
Version 6.5.7 of The Server Framework was released today.

This release contains one important bug fix and support for Visual Studio 2012 RTM. The bug that was introduced in 6.5.6 has exposed a gap in our unit testing which has also been filled with this release.

If you use either the Read Timeout filter or VS2012 RTM then you should install this update.

This release includes the following, see the release notes, here, for full details of all changes.

  • Updated our support of Visual Studio 2012 to the RTM version. Added a few more warning suppressions. Fixed the solution file format so that it's actually a 2012 solution file and not a 2010 solution file using the 2012 tool chain.
  • Bug fix to the changes in 6.5.6 to CReadTimeoutStreamSocketConnectionFilter. The 'connection closed' data is per connection and not per filter. The bug manifests as timers not being set on any connections once a single connection has closed.
  • Added unit tests for CReadTimeoutStreamSocketConnectionFilter.

Latest release of The Server Framework: 6.5.6

| 0 Comments
Version 6.5.6 of The Server Framework was released today.

This release contains some bug fixes, a selection of minor improvements and improved support for the Visual Studio 2012 (Note that there will be a further release shortly after Visual Studio 2012's RTM if needed to address any changes between the Release Candidate and the RTM versions).

If you use either the Read Timeout filter or the Flow Control filter then you should install this update. If you use the Service Tools library there are several improvements which make automating service installation and removal easier and make handling complex multi-instance start up restrictions easier.

Follow us on Twitter: @ServerFramework

About this Archive

This page is an archive of entries from August 2012 listed from newest to oldest.

July 2012 is the previous archive.

September 2012 is the next archive.

I usually write about the development of The Server Framework, a super scalable, high performance, C++, I/O Completion Port based framework for writing servers and clients on Windows platforms.

Find recent content on the main index or look in the archives to find all content.