And you lose the point on that one.  The rest of the *system* is just as
responsive if your app is blocked on IO or not.

If that were true, then I wouldn't have needed to worry about my comms code
hogging the CPU.

I don't think you're reading what I posted. *blocked IO*. If your app does a read that blocks, the app (more specifically "that thread", and in a single-thread app it's effectively the whole app) is put to sleep until the IO completes. That thread/app doesn't eat up any CPU cycles.


And you also chopped the context of my statement. We're talking about CFile and ReadHuge( ), and I'm pointing out that waiting on a read whether it's a blocked IO (where the thread blocks until the IO is completed) or overlapped (where the thread continues to execute other things while the IO is being performed) it won't matter to the rest of the system. The *IO*. Now if overlapped is used and the thread runs on in circles, sure it can still bog down the CPU, but the *IO* doesn't whether it's blocked or not.

So I'll restate myself.  You said:

{:v) But it should make the system more
responsive while it loads it, I guess, using overlapped.

And I say (maybe a little more clearly):

The rest of the OS is just as responsive if your app is blocked on IO (where the app is waiting for the IO to complete) or if your app did the IO overlapped (where the app isn't waiting on the IO).

Think about it, for sure the system is more responsive if you actually block on the IO in a single-IO model, like the ReadHuge( ) we're talking about here (almost sounds backwards doesn't it?). If you *don't* block on the IO and your thread runs on and does other things that's going to eat up CPU. If it blocks on the IO the thread is put in sleep mode and won't be scheduled to run until the IO completes, which eats less CPU and lets the CPU be used by other threads on the system. In general this "gain" isn't seen.

Now when you have many many IOs going on simultaneously, this is where overlapped really pays off.

Overlapped IO isn't really to help the system perform better, even though that does happen, it's to help the app perform better. Typically you have a number of worker threads (thread pool) that do nothing but wait for IO to complete, and then they handle the next piece of CPU-bound processing related to that IOs completion, possibly including firing off other async IO. Thus a small number of threads can handle a huge number of IO sources (usually network connections). If you use IOCP (yes you can do async IO with a thread pool without using IOCP but just not as effectively) the first thread works until there are no other IO completions or his time slice expires. If there are more IO completions on the IOCP the next thread is woke up and it gets busy handling IO completions. On it goes until enough of the thread pool is awoke to handle all the IOs *or* all the threads have been activated and are busy working. They scale up to meet demand and scale back down when not needed automatically. And that makes a *huge* difference on how well that application performs. Let's compare that to one-thread-per connection model. None of this would be possible if each network connection (IO source) had it's own thread to handle it's data. Each thread has a certain amount of overhead in the app and the kernel, and while in the IOCP model one thread could potentially handle all the current IO completions, the one-thread-per-connection model requires a context switch (which is CPU expensive) between each IO completion that is handled.

OK, I've gotten off the topic so I'll stop rambling on...


_______________________________________________ msvc mailing list [email protected] See http://beginthread.com/mailman/listinfo/msvc_beginthread.com for subscription changes, and list archive.

Reply via email to