views:

487

answers:

4

One of the features of asynchronous programming in .NET is saving threads during long running operation execution. The FileStream class can be setup to allow asynchronous operations, that allows running (e.g.) a copy operation without virtually using any threads. To my surprise, I found that running asynchronous stream copy performs not only slower, but also uses more processing power than synchronous stream copy equivalent.

Is there any benchmark tests were done to compare a synchronous vs asynchronous operation execution (file, network, etc.)? Does it really make sense to perform an asynchronous operation instead of spanning separate thread and perform synchronous operation in server environment if the asynchronous operation is times slower than the synchronous one?

+1  A: 

Are you sure that you benchmarked your copy operation correctly? Any asynchronous operation just create new thread and runs the operation in new thread while leaving main thread to do other things.

The asynchronous operations mostly give a a few simplifications(less lines of code) over creating the thread yourself but they should not impact performance more then creating a new Thread.

Alex Reitbort
Pure asynchronous operations relay on hardware to invoke callbacks and they not spanning a new thread
LicenseQ
What is "Pure asynchronous operation"? can you provide some links?
Alex Reitbort
http://msdn.microsoft.com/en-us/library/aa365683(VS.85).aspx
LicenseQ
+2  A: 

Esentially all I/O in Windows is asynchronous. Actually synchronous I/O is just "doing async I/O and waiting for it to finish".

However when you're doing asynchronous I/O, your thread is allowed to do other work, which can delay I/O processing of course, depending on what you're doing at the moment. If you're doing disk access during async I/O your performance should be halved at least since disk accesses have to be serialized.

However CPU intensive operations in the foreground should not affect async I/O performance since an interrupt from storage controller would "interrupt" the execution of the thread immediately and proceed to interrupt -> DPC flow, without waiting for your operation.

To summarize you should not be seeing any performance impact unless you're doing another I/O in the foreground.

ssg
First statement is not true for FileStream (see implementation). In test I did it performed different from what you described.
LicenseQ
Unless FileStream comes with its own Windows NT Kernel there is no way that FileStream can control how I/O is performed at kernel level. And that is aync I/O in the end.
ssg
A: 

Quoting from the article you included in your comment to @Alex's response.

In situations where an I/O request is expected to take a large amount of time, such as a refresh or backup of a large database or a slow communications link, asynchronous I/O is generally a good way to optimize processing efficiency. However, for relatively fast I/O operations, the overhead of processing kernel I/O requests and kernel signals may make asynchronous I/O less beneficial, particularly if many fast I/O operations need to be made. In this case, synchronous I/O would be better. The mechanisms and implementation details of how to accomplish these tasks vary depending on the type of device handle that is used and the particular needs of the application. In other words, there are usually multiple ways to solve the problem.

FWIW, I think @Alex is correct that there is another thread running the kernel code associated with your I/O request. That thread is not managed by your application, though. The thread running the kernel code may itself block on an device I/O request and wait for the actual hardware to complete the request before signaling your user-mode thread, but it is still there nonetheless.

Using asynchronous threads shouldn't be thought of as a way to increase the speed of any particular request, but rather a way to increase the overall efficiency by allowing your application to continue processing on other tasks while awaiting relatively slow I/O.

tvanfosson
Async I/O does not use threads on Windows NT. A storage driver may choose to use kernel worker threads however that would be very inefficient since threads are expensive in kernel mode.
ssg
I think it's really a matter of semantics. Whether you're using the kernel process or spawning a new kernel thread, there is still code running in kernel-mode on the calling thread's behalf to do the I/O operation. You can't get away from some kernel code running to service the I/O operation.
tvanfosson
That operation does not run in a separate thread. The storage devices are capable of performing I/O unattended and signal interrupts when they are done. That interrupt's "cleanup work" is done in one of existing threads without creating a new one.
ssg
I didn't say that it created a new thread. I said it ran in a different thread than the user thread.
tvanfosson
+1  A: 

Actually, the conditions under which file i/o will be actually be asynchronous are rather specific, even at the native Win32 level. See this article for more details.

Nick Gunn