473,899 Members | 3,641 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

context switch

Hi,

I have a client/server application, using one thread/client approach.

I see very high context switch/sec. What are the ways to reduce it? Each
thread sleep longer in its endless loop if not reducing thread?

On the same machine, I also run a mysql server. I can see same amount thread
in mysqld, seems mysql is also using one thread/client. But its
context/swith is much lower. How can I get same performance?

Thanks a lot!
Ryan

Jun 27 '08
28 5577


"Peter Duniho" wrote:
On Sun, 01 Jun 2008 20:32:58 -0700, Ryan Liu <rl**@powercati .comwrote:
The customer complains to me. So I changed back to one thread per client
with sync read/write approach. And have't dare try async again.
Oh, virus were found before on the customer's network and maybe still
there.

Viruses on computers are a bad idea, no matter what. :) On the other
hand, it's possible you did something wrong in the async implementation
that caused the server to terminate prematurely. Or the virus could have
done it. One reason it's so bad to have a virus on the computer is that
when weird things happen, it's harder to know for sure it's your own code
that's causing the problem.

That said, if the virus were killing the server after 15 minutes with the
async implementation, I'd think it would with the current implementation
too. There's no way from here to know for sure, but it sounds like the
implementation itself might have had bugs.
[...]
If you are in fact not dedicating a single thread to a particular
client's
read and write both, but rather (as it seems from the vague information
you've provided so far) polling for reads and queuing each write to the
thread pool individually, then that seems like that would in fact be one
of the worst ways to try to implement a "one thread/client" design.
Are you sure this is the worest way? Then I made a big mistake.
I am doing just that.

Sorry to say, yes. Think about what you're doing. On the one hand, it's
nice that you're sleeping. On the other hand, if you are sleeping between
each read, then you are forcing a context switch between each read. Even
if you're only sleeping when you run out of reads, you're still assigning
a different thread to each write operation. Again, this forces a context
switch for each write operation.

Basically, with each i/o operation, you force a context switch.
If you are pretty sure, then I will change the code -- either dedicated
thread or try async I/O again.

Please do. At the very minimum, take out the sleeps, and dedicate a
thread to each client. That way, the Windows thread scheduler can make
sure that any given thread will run as long as possible before a context
switch happens. Either the thread will run out of things to do, or it
will use up its timeslice when there's another thread ready to run.

Using the async API would be much better even still, but even switching to
a dedicated thread for each client would improve things a _lot_ as
compared to your current implementation.
[...]
Thank you very much, Pete!

You're welcome. Happy to help if I can. :)

Pete
[Sorry, called out and now access news group from public computer]

Long time ago, I remember if I take out sleeps, then the server will be
very busy and slow. Back then, I only have 16 clients connect to the
server. Now I have 120.

Current code looks like this, old code for 16 clients should be similar:
while(true){
if(!stream.Data Available) {Thread.Sleep(2 00); continue};
int got = stream.Read(buf fer, offset, size);
if(got ==0) {sleep(200);con tinue};}
//deal with data;
//then send response back using ThreadPool;
}
In the async code, I don't use while(true), just

BeginReadCallBa ck()
{

EndRead();
deal read msg;

BeginRead(,,, new AsyncCallBack(B eginReadCallBac k)); //call function self
}
and no need sleep anywhere. Is this right way? I heard async coding is
complex, mine is so simple and make me doubt I write in wrong way.

Pete, From your response, I understand async I/O is best, dedicated
threads(120 threads) is better. But I am still not confident to take out
sleep from each dedicated thread. I am afraid it will keep server busy.

I thought if in each loop of each thread, if it sleeps longer, there will be
less context switch. While one thread sleeps, it can give other threads more
time to run, no need swith back to or the first thread. -- this is totally
wrong idea?

Thanks again!
Jun 27 '08 #21
On Mon, 02 Jun 2008 02:01:00 -0700, Ryan <Ry**@discussio ns.microsoft.co m
wrote:
[...]
Long time ago, I remember if I take out sleeps, then the server will be
very busy and slow. Back then, I only have 16 clients connect to the
server. Now I have 120.

Current code looks like this, old code for 16 clients should be similar:
while(true){
if(!stream.Data Available) {Thread.Sleep(2 00); continue};
int got = stream.Read(buf fer, offset, size);
if(got ==0) {sleep(200);con tinue};}
//deal with data;
//then send response back using ThreadPool;
}
Right. This is polling, and this is awful.

Calling Thread.Sleep() helps avoid this particular thread from completely
consuming all available CPU time, and from starving other threads. But
the polling causes your context switching to actually increase, because if
you'd use a different i/o mechanism, that thread would be able to not run
at all until there was actually something to do. As it is, it has to wake
up every 200 ms just to see if there's data to be read, which causes a
context switch even when there's no data to be read.

Of course, the other bad thing that sleeping does is that it forces that
thread to wait as long as 200 ms before it can do any work, increasing
latency.

The one good thing I can say about that code is that at least you only
sleep when you believe you have nothing to do (though, a 0-byte read means
that the stream has closed, which you don't seem to deal with in the code
sample above). So at least the thread keeps the CPU as long as it can,
when it has work to do.

But otherwise, it's a terrible way to do i/o.
In the async code, I don't use while(true), just

BeginReadCallBa ck()
{

EndRead();
deal read msg;

BeginRead(,,, new AsyncCallBack(B eginReadCallBac k)); //call function
self
}
and no need sleep anywhere. Is this right way? I heard async coding is
complex, mine is so simple and make me doubt I write in wrong way.
I know. :) But it really is just that simple. It's one of the reasonsI
like the async API so much. Asynchronous coding can be complex in the
sense that you have to mentally accomodate the possibility of
multi-threaded access to data structures. But since you're using
threading already, you already have this complexity in your code, but
without the inherent advantage of simplicity that the async API otherwise
provides.
Pete, From your response, I understand async I/O is best, dedicated
threads(120 threads) is better. But I am still not confident to take out
sleep from each dedicated thread. I am afraid it will keep server busy.
No. The async API is essentially a blocking API. That's one of the
things that makes it so useful. It has the same advantage that the
regular blocking API has (that is, you aren't consuming any CPU resources
unless there's actual i/o work to do) but the same advantage that a
multi-threaded implementation has: you can easily handle a relatively
arbitrary number of clients with code that is essentially the same as if
you were dealing with a single client (that is, the bulk of the code looks
the same as if you only had to deal with one client instead of many).

With the async API, there is no "dedicated thread". A thread is assigned
as needed to each i/o operation that completes. But it's done in a much
more efficient way than your current way of dealing with writes. You are
queuing each write operation to the thread pool, which adds a lot of
overhead. But the async API has threads that are specifically for dealing
with i/o operations (in this sense they are "dedicated" , but you're not
the one dedicating them :) ), and they just pull completed i/o operations
out of a queue as long as they exist.

If the queue is empty, there's nothing to do and Windows doesn't run any
of the threads. They simply block, consuming no CPU resources. If a
given thread already has the CPU, and there are i/o operation completions
in the queue, Windows will let that thread continue to run for as long as
is practical, rather than switching to a different thread.

Now, even if you dedicate a single thread to each client, you can avoid
the problems of the polling implementation you posted, by using the
blocking API without checking for data availability. Just call
Stream.Read(). It won't return until there's data available to read, and
the thread will not consume any CPU resources. Windows knows that the
thread can't do anything until the call to Read() completes, and won't
schedule that thread until then.

But using the async API you will avoid one problem that even the correct
"dedicated single thread/client" implementation would have: context
switches related to having multiple clients to service. With one thread
dedicated to each client, if you have i/o operations for multiple clients
that have completed, you will still be forced to have a context switch to
deal with each client, because each thread knows about only one client.
But using the async API, Windows is able to keep using the same thread to
handle i/o completions on multiple connections, avoiding any context
switches related to dealing with multiple clients.
I thought if in each loop of each thread, if it sleeps longer, there
will be
less context switch. While one thread sleeps, it can give other threads
more
time to run, no need swith back to or the first thread. -- this is
totally
wrong idea?
Yes. It's not clear from your post whether that loop exists in a single
thread that manages multiple connections, or is being executed in multiple
threads, one thread per connection. But either way, the big problem with
the loop is that you are explicitly checking the DataAvailable property,
rather than just calling Read().

If you would just call Read(), then the thread would remain blocked until
there's data to be returned, and would not use any CPU time at all. But
as it is now, you only call Read() when you expect it to return right
away, which means that Windows has to keep scheduling that thread for
execution. Each thread is pretty much guaranteed to have to run 5 timesa
second, even for a thread that's dealing with a connection that doesn't
have any i/o happening.

In this scenario, calling Thread.Sleep() is certainly better than not
calling Thread.Sleep(). But you shouldn't be in "this scenario" in the
first place. Polling -- that is, checking the DataAvailable property --
isn't useful, and it causes the performance issues you're seeing.

Personally, I like the async API and that's how I'd do this. But,
assuming that you already have a dedicated thread for each connection, you
may be able to fix things just by taking out the check for DataAvailable,
taking out the calls to Thread.Sleep(), and taking out the queuing of
write operations to the ThreadPool (just do the writes from the same
thread that is handling reads). In other words, most of what's wrong with
your current implementation may well just be that you have too much code..
:)

Pete
Jun 27 '08 #22
[I always see weird things, when I reply, it does not add '' for each line
for this particular message. I had to write a code to add it :-)]
>"Peter Duniho" <Np*********@nn owslpianmk.com Ϣ:op* **************@ petes-computer.local. ..
On Mon, 02 Jun 2008 02:01:00 -0700, Ryan <Ry**@discussio ns.microsoft.co m>
wrote:
>[...]
Long time ago, I remember if I take out sleeps, then the server will be
very busy and slow. Back then, I only have 16 clients connect to the
server. Now I have 120.

Current code looks like this, old code for 16 clients should be similar:
while(true){
if(!stream.Data Available) {Thread.Sleep(2 00); continue};
int got = stream.Read(buf fer, offset, size);
if(got ==0) {sleep(200);con tinue};}
//deal with data;
//then send response back using ThreadPool;
}

Right. This is polling, and this is awful.

Calling Thread.Sleep() helps avoid this particular thread from completely
consuming all available CPU time, and from starving other threads. But
the polling causes your context switching to actually increase, because if
you'd use a different i/o mechanism, that thread would be able to not run
at all until there was actually something to do. As it is, it has to wake
up every 200 ms just to see if there's data to be read, which causes a
context switch even when there's no data to be read.

Of course, the other bad thing that sleeping does is that it forces that
thread to wait as long as 200 ms before it can do any work, increasing
latency.

The one good thing I can say about that code is that at least you only
sleep when you believe you have nothing to do (though, a 0-byte read means
that the stream has closed, which you don't seem to deal with in the code
sample above). So at least the thread keeps the CPU as long as it can,
when it has work to do.

But otherwise, it's a terrible way to do i/o.
>In the async code, I don't use while(true), just

BeginReadCallB ack()
{

EndRead();
deal read msg;

BeginRead(,,, new AsyncCallBack(B eginReadCallBac k)); //call function
self
}
and no need sleep anywhere. Is this right way? I heard async coding is
complex, mine is so simple and make me doubt I write in wrong way.

I know. :) But it really is just that simple. It's one of the reasons I
like the async API so much. Asynchronous coding can be complex in the
sense that you have to mentally accomodate the possibility of
multi-threaded access to data structures. But since you're using
threading already, you already have this complexity in your code, but
without the inherent advantage of simplicity that the async API otherwise
provides.
>Pete, From your response, I understand async I/O is best, dedicated
threads(120 threads) is better. But I am still not confident to take out
sleep from each dedicated thread. I am afraid it will keep server busy.

No. The async API is essentially a blocking API. That's one of the
things that makes it so useful. It has the same advantage that the
regular blocking API has (that is, you aren't consuming any CPU resources
unless there's actual i/o work to do) but the same advantage that a
multi-threaded implementation has: you can easily handle a relatively
arbitrary number of clients with code that is essentially the same as if
you were dealing with a single client (that is, the bulk of the code looks
the same as if you only had to deal with one client instead of many).

With the async API, there is no "dedicated thread". A thread is assigned
as needed to each i/o operation that completes. But it's done in a much
more efficient way than your current way of dealing with writes. You are
queuing each write operation to the thread pool, which adds a lot of
overhead. But the async API has threads that are specifically for dealing
with i/o operations (in this sense they are "dedicated" , but you're not
the one dedicating them :) ), and they just pull completed i/o operations
out of a queue as long as they exist.

If the queue is empty, there's nothing to do and Windows doesn't run any
of the threads. They simply block, consuming no CPU resources. If a
given thread already has the CPU, and there are i/o operation completions
in the queue, Windows will let that thread continue to run for as long as
is practical, rather than switching to a different thread.

Now, even if you dedicate a single thread to each client, you can avoid
the problems of the polling implementation you posted, by using the
blocking API without checking for data availability. Just call
Stream.Read( ). It won't return until there's data available to read, and
the thread will not consume any CPU resources. Windows knows that the
thread can't do anything until the call to Read() completes, and won't
schedule that thread until then.

But using the async API you will avoid one problem that even the correct
"dedicated single thread/client" implementation would have: context
switches related to having multiple clients to service. With one thread
dedicated to each client, if you have i/o operations for multiple clients
that have completed, you will still be forced to have a context switch to
deal with each client, because each thread knows about only one client.
But using the async API, Windows is able to keep using the same thread to
handle i/o completions on multiple connections, avoiding any context
switches related to dealing with multiple clients.
>I thought if in each loop of each thread, if it sleeps longer, there
will be
less context switch. While one thread sleeps, it can give other threads
more
time to run, no need swith back to or the first thread. -- this is
totally
wrong idea?

Yes. It's not clear from your post whether that loop exists in a single
thread that manages multiple connections, or is being executed in multiple
threads, one thread per connection. But either way, the big problem with
the loop is that you are explicitly checking the DataAvailable property,
rather than just calling Read().

If you would just call Read(), then the thread would remain blocked until
there's data to be returned, and would not use any CPU time at all. But
as it is now, you only call Read() when you expect it to return right
away, which means that Windows has to keep scheduling that thread for
execution. Each thread is pretty much guaranteed to have to run 5 times a
second, even for a thread that's dealing with a connection that doesn't
have any i/o happening.

In this scenario, calling Thread.Sleep() is certainly better than not
calling Thread.Sleep(). But you shouldn't be in "this scenario" in the
first place. Polling -- that is, checking the DataAvailable property --
isn't useful, and it causes the performance issues you're seeing.

Personally, I like the async API and that's how I'd do this. But,
assuming that you already have a dedicated thread for each connection, you
may be able to fix things just by taking out the check for DataAvailable,
taking out the calls to Thread.Sleep(), and taking out the queuing of
write operations to the ThreadPool (just do the writes from the same
thread that is handling reads). In other words, most of what's wrong with
your current implementation may well just be that you have too much code.
:)

Pete
Thanks you so much, Pete!

I will use async I/O, and do not create any thread myself for clients
(except main thread listen and accept income connect request), and give a
try. I will post back results.

Anything particulare I should pay attention about async I/O?
Jun 27 '08 #23
[I always see weird things, when I reply, it does not add '' for each line
for this particular message. I had to write a code to add it :-)]
>"Peter Duniho" <Np*********@nn owslpianmk.com Ϣ:op* **************@ petes-computer.local. ..
On Mon, 02 Jun 2008 02:01:00 -0700, Ryan <Ry**@discussio ns.microsoft.co m>
wrote:
>[...]
Long time ago, I remember if I take out sleeps, then the server will be
very busy and slow. Back then, I only have 16 clients connect to the
server. Now I have 120.

Current code looks like this, old code for 16 clients should be similar:
while(true){
if(!stream.Data Available) {Thread.Sleep(2 00); continue};
int got = stream.Read(buf fer, offset, size);
if(got ==0) {sleep(200);con tinue};}
//deal with data;
//then send response back using ThreadPool;
}

Right. This is polling, and this is awful.

Calling Thread.Sleep() helps avoid this particular thread from completely
consuming all available CPU time, and from starving other threads. But
the polling causes your context switching to actually increase, because if
you'd use a different i/o mechanism, that thread would be able to not run
at all until there was actually something to do. As it is, it has to wake
up every 200 ms just to see if there's data to be read, which causes a
context switch even when there's no data to be read.

Of course, the other bad thing that sleeping does is that it forces that
thread to wait as long as 200 ms before it can do any work, increasing
latency.

The one good thing I can say about that code is that at least you only
sleep when you believe you have nothing to do (though, a 0-byte read means
that the stream has closed, which you don't seem to deal with in the code
sample above). So at least the thread keeps the CPU as long as it can,
when it has work to do.

But otherwise, it's a terrible way to do i/o.
>In the async code, I don't use while(true), just

BeginReadCallB ack()
{

EndRead();
deal read msg;

BeginRead(,,, new AsyncCallBack(B eginReadCallBac k)); //call function
self
}
and no need sleep anywhere. Is this right way? I heard async coding is
complex, mine is so simple and make me doubt I write in wrong way.

I know. :) But it really is just that simple. It's one of the reasons I
like the async API so much. Asynchronous coding can be complex in the
sense that you have to mentally accomodate the possibility of
multi-threaded access to data structures. But since you're using
threading already, you already have this complexity in your code, but
without the inherent advantage of simplicity that the async API otherwise
provides.
>Pete, From your response, I understand async I/O is best, dedicated
threads(120 threads) is better. But I am still not confident to take out
sleep from each dedicated thread. I am afraid it will keep server busy.

No. The async API is essentially a blocking API. That's one of the
things that makes it so useful. It has the same advantage that the
regular blocking API has (that is, you aren't consuming any CPU resources
unless there's actual i/o work to do) but the same advantage that a
multi-threaded implementation has: you can easily handle a relatively
arbitrary number of clients with code that is essentially the same as if
you were dealing with a single client (that is, the bulk of the code looks
the same as if you only had to deal with one client instead of many).

With the async API, there is no "dedicated thread". A thread is assigned
as needed to each i/o operation that completes. But it's done in a much
more efficient way than your current way of dealing with writes. You are
queuing each write operation to the thread pool, which adds a lot of
overhead. But the async API has threads that are specifically for dealing
with i/o operations (in this sense they are "dedicated" , but you're not
the one dedicating them :) ), and they just pull completed i/o operations
out of a queue as long as they exist.

If the queue is empty, there's nothing to do and Windows doesn't run any
of the threads. They simply block, consuming no CPU resources. If a
given thread already has the CPU, and there are i/o operation completions
in the queue, Windows will let that thread continue to run for as long as
is practical, rather than switching to a different thread.

Now, even if you dedicate a single thread to each client, you can avoid
the problems of the polling implementation you posted, by using the
blocking API without checking for data availability. Just call
Stream.Read( ). It won't return until there's data available to read, and
the thread will not consume any CPU resources. Windows knows that the
thread can't do anything until the call to Read() completes, and won't
schedule that thread until then.

But using the async API you will avoid one problem that even the correct
"dedicated single thread/client" implementation would have: context
switches related to having multiple clients to service. With one thread
dedicated to each client, if you have i/o operations for multiple clients
that have completed, you will still be forced to have a context switch to
deal with each client, because each thread knows about only one client.
But using the async API, Windows is able to keep using the same thread to
handle i/o completions on multiple connections, avoiding any context
switches related to dealing with multiple clients.
>I thought if in each loop of each thread, if it sleeps longer, there
will be
less context switch. While one thread sleeps, it can give other threads
more
time to run, no need swith back to or the first thread. -- this is
totally
wrong idea?

Yes. It's not clear from your post whether that loop exists in a single
thread that manages multiple connections, or is being executed in multiple
threads, one thread per connection. But either way, the big problem with
the loop is that you are explicitly checking the DataAvailable property,
rather than just calling Read().

If you would just call Read(), then the thread would remain blocked until
there's data to be returned, and would not use any CPU time at all. But
as it is now, you only call Read() when you expect it to return right
away, which means that Windows has to keep scheduling that thread for
execution. Each thread is pretty much guaranteed to have to run 5 times a
second, even for a thread that's dealing with a connection that doesn't
have any i/o happening.

In this scenario, calling Thread.Sleep() is certainly better than not
calling Thread.Sleep(). But you shouldn't be in "this scenario" in the
first place. Polling -- that is, checking the DataAvailable property --
isn't useful, and it causes the performance issues you're seeing.

Personally, I like the async API and that's how I'd do this. But,
assuming that you already have a dedicated thread for each connection, you
may be able to fix things just by taking out the check for DataAvailable,
taking out the calls to Thread.Sleep(), and taking out the queuing of
write operations to the ThreadPool (just do the writes from the same
thread that is handling reads). In other words, most of what's wrong with
your current implementation may well just be that you have too much code.
:)

Pete
Thanks you so much, Pete! Your long response clarify lots of things for me.

I will use async I/O, and do not create any thread myself for clients
(except main thread listen and accept income connect request), and give a
try. I will post back results.

Anything particular I should pay attention about async I/O?

Jun 27 '08 #24
[I always see weird things, when I reply, it does not add '' for each line
for this particular message. I had to write a code to add it :-)]
>"Peter Duniho" <Np*********@nn owslpianmk.com Ϣ:op* **************@ petes-computer.local. ..
On Mon, 02 Jun 2008 02:01:00 -0700, Ryan <Ry**@discussio ns.microsoft.co m>
wrote:
>[...]
Long time ago, I remember if I take out sleeps, then the server will be
very busy and slow. Back then, I only have 16 clients connect to the
server. Now I have 120.

Current code looks like this, old code for 16 clients should be similar:
while(true){
if(!stream.Data Available) {Thread.Sleep(2 00); continue};
int got = stream.Read(buf fer, offset, size);
if(got ==0) {sleep(200);con tinue};}
//deal with data;
//then send response back using ThreadPool;
}

Right. This is polling, and this is awful.

Calling Thread.Sleep() helps avoid this particular thread from completely
consuming all available CPU time, and from starving other threads. But
the polling causes your context switching to actually increase, because if
you'd use a different i/o mechanism, that thread would be able to not run
at all until there was actually something to do. As it is, it has to wake
up every 200 ms just to see if there's data to be read, which causes a
context switch even when there's no data to be read.

Of course, the other bad thing that sleeping does is that it forces that
thread to wait as long as 200 ms before it can do any work, increasing
latency.

The one good thing I can say about that code is that at least you only
sleep when you believe you have nothing to do (though, a 0-byte read means
that the stream has closed, which you don't seem to deal with in the code
sample above). So at least the thread keeps the CPU as long as it can,
when it has work to do.

But otherwise, it's a terrible way to do i/o.
>In the async code, I don't use while(true), just

BeginReadCallB ack()
{

EndRead();
deal read msg;

BeginRead(,,, new AsyncCallBack(B eginReadCallBac k)); //call function
self
}
and no need sleep anywhere. Is this right way? I heard async coding is
complex, mine is so simple and make me doubt I write in wrong way.

I know. :) But it really is just that simple. It's one of the reasons I
like the async API so much. Asynchronous coding can be complex in the
sense that you have to mentally accomodate the possibility of
multi-threaded access to data structures. But since you're using
threading already, you already have this complexity in your code, but
without the inherent advantage of simplicity that the async API otherwise
provides.
>Pete, From your response, I understand async I/O is best, dedicated
threads(120 threads) is better. But I am still not confident to take out
sleep from each dedicated thread. I am afraid it will keep server busy.

No. The async API is essentially a blocking API. That's one of the
things that makes it so useful. It has the same advantage that the
regular blocking API has (that is, you aren't consuming any CPU resources
unless there's actual i/o work to do) but the same advantage that a
multi-threaded implementation has: you can easily handle a relatively
arbitrary number of clients with code that is essentially the same as if
you were dealing with a single client (that is, the bulk of the code looks
the same as if you only had to deal with one client instead of many).

With the async API, there is no "dedicated thread". A thread is assigned
as needed to each i/o operation that completes. But it's done in a much
more efficient way than your current way of dealing with writes. You are
queuing each write operation to the thread pool, which adds a lot of
overhead. But the async API has threads that are specifically for dealing
with i/o operations (in this sense they are "dedicated" , but you're not
the one dedicating them :) ), and they just pull completed i/o operations
out of a queue as long as they exist.

If the queue is empty, there's nothing to do and Windows doesn't run any
of the threads. They simply block, consuming no CPU resources. If a
given thread already has the CPU, and there are i/o operation completions
in the queue, Windows will let that thread continue to run for as long as
is practical, rather than switching to a different thread.

Now, even if you dedicate a single thread to each client, you can avoid
the problems of the polling implementation you posted, by using the
blocking API without checking for data availability. Just call
Stream.Read( ). It won't return until there's data available to read, and
the thread will not consume any CPU resources. Windows knows that the
thread can't do anything until the call to Read() completes, and won't
schedule that thread until then.

But using the async API you will avoid one problem that even the correct
"dedicated single thread/client" implementation would have: context
switches related to having multiple clients to service. With one thread
dedicated to each client, if you have i/o operations for multiple clients
that have completed, you will still be forced to have a context switch to
deal with each client, because each thread knows about only one client.
But using the async API, Windows is able to keep using the same thread to
handle i/o completions on multiple connections, avoiding any context
switches related to dealing with multiple clients.
>I thought if in each loop of each thread, if it sleeps longer, there
will be
less context switch. While one thread sleeps, it can give other threads
more
time to run, no need swith back to or the first thread. -- this is
totally
wrong idea?

Yes. It's not clear from your post whether that loop exists in a single
thread that manages multiple connections, or is being executed in multiple
threads, one thread per connection. But either way, the big problem with
the loop is that you are explicitly checking the DataAvailable property,
rather than just calling Read().

If you would just call Read(), then the thread would remain blocked until
there's data to be returned, and would not use any CPU time at all. But
as it is now, you only call Read() when you expect it to return right
away, which means that Windows has to keep scheduling that thread for
execution. Each thread is pretty much guaranteed to have to run 5 times a
second, even for a thread that's dealing with a connection that doesn't
have any i/o happening.

In this scenario, calling Thread.Sleep() is certainly better than not
calling Thread.Sleep(). But you shouldn't be in "this scenario" in the
first place. Polling -- that is, checking the DataAvailable property --
isn't useful, and it causes the performance issues you're seeing.

Personally, I like the async API and that's how I'd do this. But,
assuming that you already have a dedicated thread for each connection, you
may be able to fix things just by taking out the check for DataAvailable,
taking out the calls to Thread.Sleep(), and taking out the queuing of
write operations to the ThreadPool (just do the writes from the same
thread that is handling reads). In other words, most of what's wrong with
your current implementation may well just be that you have too much code.
:)

Pete
Thanks you so much, Pete! Your long response clarify lots of things for me.

I will use async I/O, and do not create any thread myself for clients
(except main thread listen and accept income connect request), and give a
try. I will post back results.

Anything particular I should pay attention about async I/O?

Jun 27 '08 #25
On Mon, 02 Jun 2008 12:04:03 -0700, Ryan Liu <rl**@powercati .comwrote:
[I always see weird things, when I reply, it does not add '' for each
line
for this particular message. I had to write a code to add it :-)]
That's because you're using Outlook Express and I'm using a news reader
that sometimes posts articles using "Quoted-Printable" as the transfer
type. Outlook Express fails to handle that format correctly, and simply
skips quoting text when composing replies to posts using that type.

There's a "quote helper" plug-in you can get for OE...I forgot the name,
but Google should be able to find it for you, especially with the above
information.
[...]
Thanks you so much, Pete!
You're welcome.
I will use async I/O, and do not create any thread myself for clients
(except main thread listen and accept income connect request), and give a
try. I will post back results.
For what it's worth, the listening API can be done async as well. It's
not strictly necessary, but if you're going to do async, why not go all
the way? :)
Anything particulare I should pay attention about async I/O?
Based one what you've already posted, I believe that you already
understand the basics. You have the essential pattern for use correct,
and you're already doing multi-threaded code so you (hopefully :) )
already understand what, if any, issues may come up with respect to
coordinating client-specific operations (which can generally all occur in
isolation within a thread) with any application-level operations (where
thread interactions might come into play, such as dealing with a GUI, or
passing computational operations off to some worker thread, etc.). The
async API doesn't introduce any new issues in that respect.

Of course, all of the usual TCP caveats apply, with respect to making sure
you're dealing with i/o as a stream. But if your code was already
basically working, again I would guess you're already familiar with these
issues.

Pete
Jun 27 '08 #26

"Peter Duniho" <Np*********@nn owslpianmk.com Ϣ:op* **************@ petes-computer.local. ..
On Mon, 02 Jun 2008 12:04:03 -0700, Ryan Liu <rl**@powercati .comwrote:
>[I always see weird things, when I reply, it does not add '' for each
line
for this particular message. I had to write a code to add it :-)]

That's because you're using Outlook Express and I'm using a news reader
that sometimes posts articles using "Quoted-Printable" as the transfer
type. Outlook Express fails to handle that format correctly, and simply
skips quoting text when composing replies to posts using that type.

There's a "quote helper" plug-in you can get for OE...I forgot the name,
but Google should be able to find it for you, especially with the above
information.
>[...]
Thanks you so much, Pete!

You're welcome.
>I will use async I/O, and do not create any thread myself for clients
(except main thread listen and accept income connect request), and give a
try. I will post back results.

For what it's worth, the listening API can be done async as well. It's
not strictly necessary, but if you're going to do async, why not go all
the way? :)
>Anything particulare I should pay attention about async I/O?

Based one what you've already posted, I believe that you already
understand the basics. You have the essential pattern for use correct,
and you're already doing multi-threaded code so you (hopefully :) )
already understand what, if any, issues may come up with respect to
coordinating client-specific operations (which can generally all occur in
isolation within a thread) with any application-level operations (where
thread interactions might come into play, such as dealing with a GUI, or
passing computational operations off to some worker thread, etc.). The
async API doesn't introduce any new issues in that respect.

Of course, all of the usual TCP caveats apply, with respect to making sure
you're dealing with i/o as a stream. But if your code was already
basically working, again I would guess you're already familiar with these
issues.

Pete
I rewote code, and tested on client's enviorment.

I wrote 2 version, one version still uses sync I/O, one server thread per
client. I remove all sleeps, and use same thread write back to client. I
also improved I/O part code. It improves performance. The CPU cost is 0
when serving 87 clients. And momory cost is 30M (My code is small, I think
mostly is .NET enviorment).

I improved sync I/O part and remove sleeps for client program as well. It
also runs faster.

But aftere few hours, client CPU cost up to 100%. I notice all files date
has been changed. I think it is because of virus. I am afraid virus is
taking advantage of new code (no sleep and more efficient I/O), so I add
sleep back to client programs. Now CPU cost is 2-3%. Runs OK. This happend
only on one machine. Other clients runs with client program without sleep,
fine.

Few more hours later, server CPU cost up to 98 too. After restart server,
server runs OK again.

I don't know why. Maybe it is the virus in network is also taking advantage
of new code which has no sleep and higher I/O effiency.

I also notice, even when the server CPU cost is 0, and all clients works
fine, sometime server is very slow to response to Service OnCustomCommand ()
which runs on server machine itself. I use it to dump server info to a file.
Thread serves network clients can also write log to this file. I use a lock
when write to this file. And ths file's change is alwo watched by another
application using a FileSystemWatch er to read (FileAccess.Rea d,
FileShare.ReadW rite) whole file cotent to a textbox. Ocz, since it is
another application, read operation it is not locked.

----------
I also tried new server with async I/O. Aftere 80 clients connected, server
crashes immediately. In the system event log, I found:

The PowerCatiAppSer vice service terminated unexpectedly. It has done this 7
time(s).
For more information, see Help and Support Center at
http://go.microsoft.com/fwlink/events.asp.

I aslo see applicatoin error in event log:
EventType clr20r3, P1 powercatiappser ver.exe, P2 1.0.3076.27877, P3
4844f3ee, P4 system, P5 2.0.0.0, P6 4333ae87, P7 282e, P8 18, P9
system.objectdi sposedexception , P10 NIL.

For more information, see Help and Support Center at
http://go.microsoft.com/fwlink/events.asp.

I think this is for sync I/O version app when it costs 100% CPU.

Thanks!
Jun 27 '08 #27
On Wed, 04 Jun 2008 00:28:57 -0700, Ryan Liu
<rl************ *@powercati.com wrote:
I rewote code, and tested on client's enviorment.

I wrote 2 version, one version still uses sync I/O, one server thread per
client. I remove all sleeps, and use same thread write back to client. I
also improved I/O part code. It improves performance. The CPU cost is 0
when serving 87 clients. And momory cost is 30M (My code is small, I
think
mostly is .NET enviorment).

I improved sync I/O part and remove sleeps for client program as well.
It
also runs faster.
Good. All that sounds just as would be expected. :)
But aftere few hours, client CPU cost up to 100%. I notice all files date
has been changed. I think it is because of virus. I am afraid virus is
taking advantage of new code (no sleep and more efficient I/O), so I add
sleep back to client programs. Now CPU cost is 2-3%. Runs OK. This
happend
only on one machine. Other clients runs with client program without
sleep,
fine.

Few more hours later, server CPU cost up to 98 too. After restart server,
server runs OK again.
This suggests, obviously, that adding a sleep doesn't help the high CPU
issue. Which isn't a surprise.
I don't know why. Maybe it is the virus in network is also taking
advantage
of new code which has no sleep and higher I/O effiency.
Absent confirmed knowledge of a virus, as well as some specific
information as to how it operates, I would not blame this behavior on a
virus. Viruses don't _usually_ "take advantage of" architectural
characteristics of random programs. I can't rule it out 100% -- after
all, virus writers can be crafty bastards :) -- but it just seems unlikely.

Instead, I think you might actually be looking for a "packrat" bug. That
is, some data structure that just keeps adding more and more things to
it. Especially if it's a data structure that you regularly scan.
Alternatively, it could be a bug where you have some escalating amount of
object instantiation. That is, as time goes by, some code that creates
multiple objects winds up creating more and more at a time. Even if they
are not "packrat"-ed, the cost of allocating and the disposing them may
consume excessive CPU time.

Without a concise-but-complete code example to look at, it's not possible
to say for sure what this might be. But I'd look for a bug in your own
code.
I also notice, even when the server CPU cost is 0, and all clients works
fine, sometime server is very slow to response to Service
OnCustomCommand ()
which runs on server machine itself.
Again, it's hard to say what might be causing this. Just a random
thought: what are the power management settings on the server? Is the
server slow to respond only when it's been idle for some time? Windows
power management will let a disk spin down, and the time it takes to get
the disk back up to speed again can cause delays in operation. Where
latency is critical, it's important to make sure the power management
settings don't idle the disks.

If that's not the issue, then again without a concise-but-complete code
sample, diagnosing it is practically impossible. It could somehow be
related to the file locking, but it also might not be.
[...]
I also tried new server with async I/O. Aftere 80 clients connected,
server
crashes immediately. In the system event log, I found:

The PowerCatiAppSer vice service terminated unexpectedly. It has done
this 7
time(s).
For more information, see Help and Support Center at
http://go.microsoft.com/fwlink/events.asp.

I aslo see applicatoin error in event log:
EventType clr20r3, P1 powercatiappser ver.exe, P2 1.0.3076.27877, P3
4844f3ee, P4 system, P5 2.0.0.0, P6 4333ae87, P7 282e, P8 18, P9
system.objectdi sposedexception , P10 NIL.
Well, that sure looks like you're trying to access an object that's
already been disposed. That would certainly be wrong. :)

Again, without a concise-but-complete code sample, impossible to say why
your code is doing that.

Note that I keep mentioning a "concise-but-complete code sample". Of
course, it's highly unlikely anyone reading this newsgroup would take the
time to navigate your entire server or client code. However, if you can
write a very small test application that implements just the basic
networking pieces you're trying to get working, that would be useful for
consideration.

Note also that it may be useful to _you_ to write such an application even
if you never post it. It's a lot easier to learn the specific techniques
and to find and fix design and coding errors when you're dealing with a
small test application that has no extraneous functionality to distract
you.

In other words, you might consider doing your learning on such a small
test application, rather than trying to implement the whole thing in-place
on production code.

Pete
Jun 27 '08 #28

"Peter Duniho" <Np*********@nn owslpianmk.com Ϣ:op* **************@ petes-computer.local. ..
On Wed, 04 Jun 2008 00:28:57 -0700, Ryan Liu
<rl************ *@powercati.com wrote:
>I rewote code, and tested on client's enviorment.

I wrote 2 version, one version still uses sync I/O, one server thread per
client. I remove all sleeps, and use same thread write back to client. I
also improved I/O part code. It improves performance. The CPU cost is 0
when serving 87 clients. And momory cost is 30M (My code is small, I
think
mostly is .NET enviorment).

I improved sync I/O part and remove sleeps for client program as well.
It
also runs faster.

Good. All that sounds just as would be expected. :)
>But aftere few hours, client CPU cost up to 100%. I notice all files date
has been changed. I think it is because of virus. I am afraid virus is
taking advantage of new code (no sleep and more efficient I/O), so I add
sleep back to client programs. Now CPU cost is 2-3%. Runs OK. This
happend
only on one machine. Other clients runs with client program without
sleep,
fine.

Few more hours later, server CPU cost up to 98 too. After restart server,
server runs OK again.

This suggests, obviously, that adding a sleep doesn't help the high CPU
issue. Which isn't a surprise.
>I don't know why. Maybe it is the virus in network is also taking
advantage
of new code which has no sleep and higher I/O effiency.

Absent confirmed knowledge of a virus, as well as some specific
information as to how it operates, I would not blame this behavior on a
virus. Viruses don't _usually_ "take advantage of" architectural
characteristics of random programs. I can't rule it out 100% -- after
all, virus writers can be crafty bastards :) -- but it just seems
unlikely.

Instead, I think you might actually be looking for a "packrat" bug. That
is, some data structure that just keeps adding more and more things to
it. Especially if it's a data structure that you regularly scan.
Alternatively, it could be a bug where you have some escalating amount of
object instantiation. That is, as time goes by, some code that creates
multiple objects winds up creating more and more at a time. Even if they
are not "packrat"-ed, the cost of allocating and the disposing them may
consume excessive CPU time.

Without a concise-but-complete code example to look at, it's not possible
to say for sure what this might be. But I'd look for a bug in your own
code.
>I also notice, even when the server CPU cost is 0, and all clients works
fine, sometime server is very slow to response to Service
OnCustomComman d()
which runs on server machine itself.

Again, it's hard to say what might be causing this. Just a random
thought: what are the power management settings on the server? Is the
server slow to respond only when it's been idle for some time? Windows
power management will let a disk spin down, and the time it takes to get
the disk back up to speed again can cause delays in operation. Where
latency is critical, it's important to make sure the power management
settings don't idle the disks.

If that's not the issue, then again without a concise-but-complete code
sample, diagnosing it is practically impossible. It could somehow be
related to the file locking, but it also might not be.
>[...]
I also tried new server with async I/O. Aftere 80 clients connected,
server
crashes immediately. In the system event log, I found:

The PowerCatiAppSer vice service terminated unexpectedly. It has done
this 7
time(s).
For more information, see Help and Support Center at
http://go.microsoft.com/fwlink/events.asp.

I aslo see applicatoin error in event log:
EventType clr20r3, P1 powercatiappser ver.exe, P2 1.0.3076.27877, P3
4844f3ee, P4 system, P5 2.0.0.0, P6 4333ae87, P7 282e, P8 18, P9
system.objectd isposedexceptio n, P10 NIL.

Well, that sure looks like you're trying to access an object that's
already been disposed. That would certainly be wrong. :)

Again, without a concise-but-complete code sample, impossible to say why
your code is doing that.

Note that I keep mentioning a "concise-but-complete code sample". Of
course, it's highly unlikely anyone reading this newsgroup would take the
time to navigate your entire server or client code. However, if you can
write a very small test application that implements just the basic
networking pieces you're trying to get working, that would be useful for
consideration.

Note also that it may be useful to _you_ to write such an application even
if you never post it. It's a lot easier to learn the specific techniques
and to find and fix design and coding errors when you're dealing with a
small test application that has no extraneous functionality to distract
you.

In other words, you might consider doing your learning on such a small
test application, rather than trying to implement the whole thing in-place
on production code.

Pete
Thanks Pete, I will ask the customer keep an eye on power management issue.
I have written a small client/server test code and tested OK. I don't have
the customer's enviorment with hundreds of computers. I will think how to
simulate it. If I have any found, I will post back here.

Thanks for pointing out directions I can looking for problems.
Ryan
Jun 27 '08 #29

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
3154
by: Johannes B. Ullrich | last post by:
--=-WKgoK98ejo9BZyGYc3N/ Content-Type: text/plain Content-Transfer-Encoding: quoted-printable I am having problems with MySQL 4.0.12 on RedHat Advanced Server 2.1 using a dual Xeon with 8 GByte of RAM. I have a database collecting logs. Each day, a new table is created. In order to allow for queries across more than one day, I use 'MERGE'
13
7482
by: William Stacey | last post by:
Using the following code sample: public byte Get() { // <= Possible to switch Here?? lock(syncLock) { //Do something in Get(). } }
5
3694
by: Nadav | last post by:
Hi, I am using FileStream's Async API: BeginRead/EndRead, upon completion callback execution I use the read data and call EndRead, Taking that in mind, I Wonder... does calling EndRead will cause a context switch? What is the kernel object used for blocking EndRead calls? Event and mutex cause a context switch even when the object is signaled and no wait is needed, usage of critical section prevent this switch from happening... what is the...
13
2117
by: Michael M. | last post by:
In Perl, it was: ## Example: "Abc | def | ghi | jkl" ## -"Abc ghi jkl" ## Take only the text betewwn the 2nd pipe (=cut the text in the 1st pipe). $na =~ s/\ \|(.*?)\ \|(.*?)\ \|/$2/g; ## -- remove in text
20
310
by: Ryan Liu | last post by:
Hi, I have a client/server application, using one thread/client approach. I see very high context switch/sec. What are the ways to reduce it? Each thread sleep longer in its endless loop if not reducing thread? On the same machine, I also run a mysql server. I can see same amount thread in mysqld, seems mysql is also using one thread/client. But its context/swith is much lower. How can I get same performance?
0
9843
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10863
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10494
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9666
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development projectplanning, coding, testing, and deploymentwithout human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
8039
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupr who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
7201
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
6081
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4720
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3317
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.