<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx</link><description>Last time , I talked a bit about why you'd use concurrency in your application. Today I'd like to talk a smidge about using concurrency to achieve scalability. The first and most important thing that you have to understand when you decide to start improving</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: Concurrency, Part 8 - COncurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#381874</link><pubDate>Mon, 28 Feb 2005 21:31:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:381874</guid><dc:creator>Ricky Datta</dc:creator><description>If you give us an example of IO competion usage (File, sockets) using C# managed code - that will be great.&lt;br&gt;&lt;br&gt;Ricky</description></item><item><title>re: Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#381880</link><pubDate>Mon, 28 Feb 2005 21:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:381880</guid><dc:creator>Larry Osterman</dc:creator><description>Ricky, are the MSDN overlapped I/O and I/O completion port examples not sufficient?  I could write something up but I'd think that there was enough sample code for that already on the web.&lt;br&gt;&lt;br&gt;Or do you have something more specific in mind?&lt;br&gt;&lt;br&gt;</description></item><item><title>re: Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#381886</link><pubDate>Mon, 28 Feb 2005 21:48:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:381886</guid><dc:creator>Ricky Datta</dc:creator><description>IO Completion ports are kind mystery..exotic to ordinary Win32 programmer. On the other hand, developer education of completion ports are essential for scalable windows server development.&lt;br&gt;&lt;br&gt;CLR FX 2.0 implements IO completion ports, which is a high productivity devlopment environment. There is very little doc/samples/established examples of how to use the following :&lt;br&gt;&lt;br&gt;AcceptEx (CLR version)&lt;br&gt;ConnectEx (CLR version)&lt;br&gt;TransmitFile (CLR version)&lt;br&gt;TransmitPackets (CLR version)&lt;br&gt;Asynchronus File/Socket operations&lt;br&gt;&lt;br&gt;In my opinion asynchronous server techniques using IO completion are usually found in MS products, never in 3rd party apps.&lt;br&gt;&lt;br&gt;If you could write about these, that would be great.&lt;br&gt;&lt;br&gt;Ricky&lt;br&gt;&lt;br&gt;&lt;br&gt;</description></item><item><title>re: Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#381925</link><pubDate>Mon, 28 Feb 2005 22:27:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:381925</guid><dc:creator>Jerry Pisk</dc:creator><description>You don't need to worry about synchronization if the data you share is read only. But it has to be read only for the lifetime of your threads. An example would be a B-tree index of your static data (such as resource strings) that is only built once, at your application startup, before you fire off your worker threads.</description></item><item><title>re: Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#381926</link><pubDate>Mon, 28 Feb 2005 22:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:381926</guid><dc:creator>Larry Osterman</dc:creator><description>Jerry, that's true.  But that relies on the fact that the data is static.  While this is likely to be true for some data sets (census data, for example) for others (Amazon.Com's book list) it's not.&lt;br&gt;</description></item><item><title>re: Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#381957</link><pubDate>Mon, 28 Feb 2005 23:10:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:381957</guid><dc:creator>Mike Dimmick</dc:creator><description>Ricky, I seem to recall there's a pretty good treatment of I/O Completion Ports - and sample code - in &amp;quot;Programming Server-Side Applications for Microsoft Windows&amp;quot; by Jeffrey Richter and Jason Clark. Unfortunately it's out of print - why, MS Press? This is an essential book! I note that Jeff's other Win32 book &amp;quot;Programming Applications for Microsoft Windows&amp;quot; is also out of print.&lt;br&gt;&lt;br&gt;As for the .NET Framework 2.0, it's still in beta and a lot of the documentation is unfinished. Hopefully Beta 2 will be a lot better in that regard.</description></item><item><title>re: Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#381990</link><pubDate>Mon, 28 Feb 2005 23:52:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:381990</guid><dc:creator>Eric Lippert</dc:creator><description>Good series Larry!&lt;br&gt;&lt;br&gt;&amp;gt; But if your application is CPU bound then the obvious solution is to throw more CPUs at the problem.&lt;br&gt;&lt;br&gt;That's one obvious &amp;quot;solution&amp;quot; that turns out to not always work.  Another obvious &amp;quot;solution&amp;quot; is to performance tune the application so that each operation is faster, AND throw more CPUs at the problem.&lt;br&gt;&lt;br&gt;Counter-intuitively, making the processor do less work on a given thread can actually DECREASE your performance, or at least wreck scalability.  Scalability is really, really hard to wrap your mind around.&lt;br&gt;&lt;br&gt;I wrote up an analogy that shows how speeding can slow you down here:&lt;br&gt;&lt;br&gt;&lt;a target="_new" href="http://weblogs.asp.net/ericlippert/archive/2003/12/01/53411.aspx"&gt;http://weblogs.asp.net/ericlippert/archive/2003/12/01/53411.aspx&lt;/a&gt;&lt;br&gt;</description></item><item><title>re: Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#381996</link><pubDate>Tue, 01 Mar 2005 00:08:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:381996</guid><dc:creator>Drew</dc:creator><description>&amp;lt;pedantic&amp;gt;&lt;br&gt;The singular is quantum. Quanta is plural. Because a slice of CPU time is neuter although I have no idea why.&lt;br&gt;&amp;lt;/pedantic&amp;gt;&lt;br&gt;&lt;br&gt;I'm also really enjoying this series. And not just because of the irony inherent in a series on parallelism. I'm eagerly awaiting tomorrow's installment.</description></item><item><title>re: Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#382001</link><pubDate>Tue, 01 Mar 2005 00:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:382001</guid><dc:creator>SeanH</dc:creator><description>Jerry, Larry mentioned writing scalable concurrent applications need a paradigm-shift in terms of how software developers think about writing applications, and I think one of these shifts is the concept of shared data and how we access it.&lt;br&gt;&lt;br&gt;I think writing scalable concurrent applications will mean having minimal access to the shared data. My guess is, you will have one huge container with a well-staged way of modify contents of that container through some sort of message passing mechanism where data to be modified is deep copied and wrapped around a message that is sent to a worker thread and the modifications sent back through another message. The container will then be in charge of determining which modifications will be committed.</description></item><item><title>re: Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#382009</link><pubDate>Tue, 01 Mar 2005 00:33:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:382009</guid><dc:creator>Larry Osterman</dc:creator><description>Drew, you're 100% right.  But every discussion I've ever had with the kernel group refers to the unit of scheduling as a quanta, not quantum.  I don't get it, but...&lt;br&gt;</description></item><item><title>re: Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#382207</link><pubDate>Tue, 01 Mar 2005 08:22:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:382207</guid><dc:creator>Mike Flasko</dc:creator><description>Larry, I agree with Ricky, a series on IO Completion ports would be great.  &lt;br&gt;&lt;br&gt;As for multithreading I typically use the following train of thought when developing:&lt;br&gt;&lt;br&gt;1. identify tasks suitable to a secondary thread&lt;br&gt;2. identify shared data (among threads)&lt;br&gt;3. of that shared data which of the data is writable (aka. find the race conditions)&lt;br&gt;4. provide mutual exclusion for the variables in step 3.&lt;br&gt;&lt;br&gt;** 5. If necessary, ensure my critical sections do not lead to thread starvation.</description></item><item><title>re: Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#382253</link><pubDate>Tue, 01 Mar 2005 10:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:382253</guid><dc:creator>MartinK</dc:creator><description>This series gets better and better. Two things that I'd welcome a bit of expansion of:&lt;br&gt;&lt;br&gt;1. &amp;quot;Avoid synchronous I/O because it blocks&amp;quot;. Out of interest, is this often true of WriteFile? Reading Inside Windows 2000, it looks as if WriteFile practically never writes a file, just schedules a lazy write and returns at once... in which case safe to use, surely?&lt;br&gt;2. Does the deep scheduling stuff inside Windows work? I'm not being offensive, it's just that we all know that concurrent code is virtually impossible to debug, and I don't want to spend 24 hours chasing an evanescent bug in my own code and then discover that it is one of those &amp;quot;edge cases in ntdll.dll that were never thought through properly&amp;quot; [Rob Earhart]. This may be why it's mostly MS that use their own completion ports and so on... the internal company &amp;quot;lore&amp;quot; will tell them which documented features have been well used and which ones haven't been used enough to be safe to rely on.&lt;br&gt;3. [ok, so I can't count!] A server app can balance the work it does for its clients in all sorts of ways, intelligently allocating CPU, memory, disk I/O... but the one thing it seems impossible to balance is bandwidth back to the clients. Example: my protocol splits big messages into a stream of smaller packets, the idea being that a small message can insert itself into the stream between those packets - helps responsiveness at the client end. Also there is then some hope of bandwidth allocation so that a client who's just requested 10MB won't lock out lots of other clients who only want 1KB each to get on with their work.&lt;br&gt;But - Windows provides massive buffers for socket output and happily hoovers up huge quantities of data that it then queues. Good for raw performance, but it makes for hellish latency [the insert-a-quick-little-packet solution won't work when there are already megabytes in the queue &amp;quot;owned&amp;quot; by Windows] and for no hope of balancing the bandwidth requirements of multiple clients.&lt;br&gt;I'm probably missing something here - one little API or callback or port or something - so any pointers would be welcome.</description></item><item><title>re: Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#382371</link><pubDate>Tue, 01 Mar 2005 14:47:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:382371</guid><dc:creator>Larry Osterman</dc:creator><description>Martin, for #1: If you're doing a synchronous write, the I/O subsystem takes a lock around each file object - which might block your thread if someone else is accessing the file object.  The fast I/O path won't typically take many locks, you're right.  But you're not guaranteed you'll take the fast I/O path.&lt;br&gt;&lt;br&gt;#2: The NT scheduler's not bad, w.r.t. scalability, and it's getting better all the time.  Earhart reads this blog (at least he comments on here :)), he may be able to answer better than I.&lt;br&gt;&lt;br&gt;#3: Let me look into that one, I'm not sure that there are solutions for rate metered delivery on the server side (other than setting the socket buffer size to something small)</description></item><item><title>re: Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#382407</link><pubDate>Tue, 01 Mar 2005 16:03:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:382407</guid><dc:creator>Skywing</dc:creator><description>Synchronous WriteFile will block after you've written more data than the cache manager will allocate for a particular file.  You should not rely on it completing instantly, particularly when the system is under load.&lt;br&gt;&lt;br&gt;I use I/O completion ports in my network server apps and I've not yet run into any problems with them.</description></item><item><title>re: Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#382600</link><pubDate>Tue, 01 Mar 2005 19:51:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:382600</guid><dc:creator>Andreas Häber</dc:creator><description>MartinK, think I can help you with #3:&lt;br&gt;Winsock uses an algorithm named Nagel which causes this buffering. If you enable TCP_NODELAY (through setsockopt or any equivalent) then Winsock will send packages straight away.&lt;br&gt;&lt;br&gt;Also you can change the send and receive buffers through setsockopt.&lt;br&gt;&lt;br&gt;For more/better information see &lt;a target="_new" href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/setsockopt_2.asp"&gt;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/setsockopt_2.asp&lt;/a&gt;</description></item><item><title>re: Concurrency, Part 8 - Concurrency for scalability</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#383480</link><pubDate>Wed, 02 Mar 2005 11:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:383480</guid><dc:creator>MartinK</dc:creator><description>Andreas, thanks. I'm not worried about small-packet latency. It's the opposite problem: if Windows lets me output 1MB of data to a socket that's connected to a dial-up client, then anything I send immediately afterwards will take at least 150 seconds to arrive. Having smaller buffers would indeed be the answer, so that my application would be able to make intelligent decisions about which packets of data to send when.&lt;br&gt;Unfortunately there's more buffering inside Windows than just the socket buffers. I've run a test: getsockopt() reports a send buffer size of 8192 bytes, but a call to send() that asks to send 1000000 bytes returns immediately, reporting that it's sent 1000000 bytes, not 8192.&lt;br&gt;</description></item><item><title>Concurrency, Part 9 - APIs that enable scalable programming</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#383686</link><pubDate>Wed, 02 Mar 2005 20:37:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:383686</guid><dc:creator>Larry Osterman's WebLog</dc:creator><description /></item><item><title>Concurrency, Part 9 - APIs that enable scalable programming</title><link>http://blogs.msdn.com/larryosterman/archive/2005/02/28/381865.aspx#383694</link><pubDate>Wed, 02 Mar 2005 20:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:383694</guid><dc:creator>Larry Osterman's WebLog</dc:creator><description /></item></channel></rss>