Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / March 2008

Tip: Looking for answers? Try searching our database.

cpu usage on multiple core system below 100%

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
herpers@wiso.uni-koeln.de - 26 Feb 2008 16:24 GMT
Hello,

I have a question about threads. I wrote an application which uses
threads to do some calculations. The threads are started using the
Thread-class and ParameterizedThreadStart-Class. On a single core
system and even on a dual core system there is no problem getting the
cpu usage to almost 100%. We also have to quad system (one AMD, one
Intel) and on both systems the usage only goes up to 80% or 90%. It
doesn't matter how many parallel calculations I start. If start the
same number of calculations but split the amount to two separate
instances of the main application (simply by starting the application
twice), I can get the usage to almost 100%.

I did a little reasearch and understand, that threads in .net are
managed threads, which is not the same as native threads. I forgot to
bookmark it, but in the newsgroup (I think) was a little threads by
two MVPs talking about threads and BeginThreadAffinity, which seem to
tie a managed thread to a single native thread. Since I am not very
well educated on the guts of thread programming I don't know, whether
this would be a soloution to my problem.

With a few words: How can I get the usage to almost 100% without
starting my application more than once? Is there a .net-only solution
or would I have to do some api-calls and mix managed and unmanaged
code (which I would like to avoid)?

(And I hope I posted to the right newsgroup) :)

Regards,
  Sascha
Peter Duniho - 26 Feb 2008 18:11 GMT
> [...]
> With a few words: How can I get the usage to almost 100% without
[quoted text clipped - 3 lines]
>
> (And I hope I posted to the right newsgroup) :)

This newsgroup is fine.  As for your question, while I haven't checked it  
myself recently, _generally_ you should not have a problem having your  
threads consume whatever CPU is available to them, assuming they are  
entirely CPU bound.

The thread affinity is a red herring, unless you're setting it.  You  
shouldn't be setting it unless you have a very specific need, and of  
course if you do set it, it's possible that you could have multiple  
threads demanding the same CPU, preventing full use of the available CPU  
time.

And yes, .NET threads are managed but my understanding is that since the  
JIT-compiled code is basically running natively, then as long as your  
threads are just simply doing things that are CPU bound there should be no  
problem with anything else preventing them from running at full-speed.

Since they're not running at full-speed that suggests that maybe they are  
not entirely CPU bound.  It's impossible to say in what way that's the  
case, however, without a good code sample.  If you pare down your code to  
the bare minimum required to reproduce the "not using 100% of the CPU"  
issue, but provide a complete sample that someone else can easily compile  
and run without any additional work, it's possible that someone can  
provide an answer as to how the code's not entirely CPU bound (or you may  
discover the answer yourself in simplifying the code).

Pete
herpers@wiso.uni-koeln.de - 26 Feb 2008 20:16 GMT
Hi,

> case, however, without a good code sample.
Ok, that takes some time (which I am very short of), but I will try to
provide a good sample.

> entirely CPU bound
That's probably a language (English->German) problem, but what do you
mean by CPU bound?
Is a thread, that uses Invoke(...) not completly cpu bound?

Regards,
  Sascha
Peter Duniho - 26 Feb 2008 21:30 GMT
> Hi,
>
>> case, however, without a good code sample.
> Ok, that takes some time (which I am very short of), but I will try to
> provide a good sample.

Please try to, if you cannot come to an answer on your own.  There's just  
no way to comment on specific behavior without having specific code to  
talk about.

>> entirely CPU bound
> That's probably a language (English->German) problem, but what do you
> mean by CPU bound?

My apologies.  The word "bound" here refers to what constrains the  
algorithm.  That is, what does the algorithm spend its time doing.  
Something that is "CPU bound" is constrained by, or bound to, the CPU.  It  
only does things that use the CPU, and does not do anything that uses some  
other component of the PC.

In reality, very few algorithms are _entirely_ CPU bound.  For example,  
even memory accesses can delay the execution of a thread, and of course  
anything that involves i/o to an even slower device (hard drive, network,  
etc.) will cause even greater delays.

But I would say that generally speaking, a thread that only does  
computational things, with or without memory access, would be considered  
"CPU bound" (if I recall correctly, the Windows Task Manager doesn't  
distinguish memory access from other CPU operations anyway, so even if  
memory access was slowing the thread down, that wouldn't show up in the  
Task Manager as reduced CPU usage).

> Is a thread, that uses Invoke(...) not completly cpu bound?

Which Invoke()?  I would say that calling Control.Invoke() would not in  
and of itself change whether a thread is CPU bound or not.  However, it  
does introduce a potential delay, and could in fact lead to reduced CPU  
utilization.  Specifically, when a thread call Invoke(), it yields the CPU  
and does not resume until the main GUI thread has had a chance to process  
the invoked delegate.

Ideally, if your application is the only CPU bound task on the computer,  
this shouldn't really reduce the CPU utilization.  As soon as the thread  
that called Invoke() blocks, waiting on the GUI thread, then the GUI  
thread should get to run, and once it's done processing messages it should  
yield, allowing the original thread to run again.  In other words, at all  
points the thread that's running is from that one process and so that one  
process should be the one getting the CPU time.

But I can't say for sure that it will, since ultimately it's Windows that  
gets to decide if and when a given thread will run.  Any time you offer  
Windows a chance to delay execution of your thread, you are potentially  
reducing your CPU utilization.

Also, I'm not sure how the operating system counts the time it takes to do  
the thread context switch.  If that time isn't included in the Task  
Manager-displayed time, and you are calling Invoke() frequently from your  
thread, then I think it's entirely possible that all of that context  
switching could indeed account for as much as 20% overhead, preventing  
your process from appearing to use all of the available CPU time as  
examined in Task Manager.

Unfortunately, I don't have first-hand information about these specific  
aspects of how CPU time is measured on Windows.  But it's certainly a  
possibility you may want to explore.  For example, try removing the calls  
to Invoke() and/or try calling Invoke() less (if you're currently updating  
the UI every operation, maybe change that so you only update the UI every  
100 operations, for example, or maybe even less frequently).

Pete
herpers@wiso.uni-koeln.de - 01 Mar 2008 17:51 GMT
Hi Peter,

I guess I found the problem...at least I could increase the cpu usage
a little bit. The main problem is, that my threads send progress
message to the gui. The gui itself inquires the threads for total
execution time every 500 ms and updates a listviewitem. Updating the
listviewitem every 500 ms was a bug. After I changed that to updating
the items only when there is a change in progress, the cpu usage went
up _a little_. The messages sent by the threads is appended to an rtf
control. I gues if I would supress these messages I could further
increase the cpu usage.

If I don't see things which aren't there I would say, that the task
manager only displays the cpu usage that's been caused by everything
else but the updating of the gui. I don't know, just a guess.

Anyways, thanks for the long answer. I learned a lot.

Regards,
  Sascha
Peter Duniho - 01 Mar 2008 18:27 GMT
> Hi Peter,
>
[quoted text clipped - 11 lines]
> manager only displays the cpu usage that's been caused by everything
> else but the updating of the gui. I don't know, just a guess. [...]

I doubt that's the case.  The Task Manager should be displaying all of the  
CPU time used by that process, regardless of where the time is spent.

I think it's more likely that by forcing thread context switches, causing  
your processing thread to have to yield at arbitrary moments, that may  
allow other _processes_ in the OS to get more CPU time than they otherwise  
normally would.  When that happens, obviously the CPU time comes from  
somewhere, which is your processing-intensive process.

You're not specific about how you interact between the two threads.  
However, one obvious solution would be to, anywhere you have a call to  
Control.Invoke(), replace it with a call to Control.BeginInvoke().  Then,  
the GUI thread will only get to process the invoked code when it's really  
its turn, and your processing thread(s) will maximize their use of the CPU.

If you've got other processes on the OS that need to run, they will always  
prevent you from getting to 100% CPU utilization on your own process.  But  
you should be able to get pretty close, and maximizing the use of your  
processing thread's time by not yielding unless absolutely necessary is  
the way to do that.

Note that switching to BeginInvoke() can improve your process's  
utilization of the CPU.  But if you are really posting an update of the  
GUI for every single change to progress, then when the GUI thread does get  
a chance to run, it's going to waste a lot of time performing updates for  
itself that the user will never see.  You'll get better utilization shown  
in Task Manager, but a lot of that time will be wasted, not making forward  
progress on your actual processing.

Better would be to update the GUI only every N iterations of your  
processing, where you pick N so that the GUI is in fact updated only every  
500 or 1000 ms or so.  But even choosing N arbtirarily as, for example,  
100 or 500 or 1000, is likely to show a noticeable improvement in  
processing time (maybe not a huge improvement, but at least measurable).

Depending on how much information you need to pass to the GUI, it may not  
actually be a bad idea to have the GUI poll the progress based on a timer  
as you were doing before.  For example, if the progress can be  
encapsulated in a single 32-bit integer, you could just make that a  
volatile field and the GUI would be able to examine it for the purpose of  
updating progress without a need for any synchronization with the  
processing thread.  Then you can use a timer to control the actual  
updating, saving the need to include some arbitrary reduction factor in  
the processing thread.  This would make the processing code simpler, and  
would make the timing of updates more reliable, rather than depending on  
some arbitrary, empirically-determined fixed iteration count for updates.

The key here is to make sure you're polling the processing thread  
correctly.  If that was a problem before in your code, then it's likely  
you were doing something inefficient in the polling.  Without any sample  
code showing what you're doing, it's impossible to say what might have  
been the problem.  But done correctly, a timer-based polling scheme should  
work fine and if you know you need to update the UI every N milliseconds,  
then it's likely the right thing to do.  Polling's only bad _most_ of the  
time.  :)

Pete
herpers@wiso.uni-koeln.de - 11 Mar 2008 07:58 GMT
Hi Peter,
[Sorry for the late reply, but I was out of the office for a couple of
days.]

> Control.Invoke(), replace it with a call to Control.BeginInvoke().  Then,
never used it before, but I will give it a try. It shouldn't make
things worse. :)

> Better would be to update the GUI only every N iterations of your
> processing, where you pick N so that the GUI is in fact updated only every
> 500 or 1000 ms or so.  But even choosing N arbtirarily as, for example,
> 100 or 500 or 1000, is likely to show a noticeable improvement in
> processing time (maybe not a huge improvement, but at least measurable).
That's what I do right now...at least for a listview of currently
running calculations. But there is another control (that rtf control I
mentioned above) that is updated immediately. Mayby I sould buffer
that into a stream (?) and flush the stream contents to the rtf
control when a gui update takes place...

Ok, the I try the BeginInvoke method, the message buffering and (also)
I will try to find unnecessary gui updates.

Thanks,
  Sascha

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.