clueless performance / threadig question

P

PJ6

I'm pushing my CPU to its limit with a realtime physics simulation to learn
more about coding for performance. In the simplest case, I have a form that,
on a timer tick, drives the physics model forward by the time elapsed since
the last tick measured by a stopwatch (since both the timer and DateTime.Now
is not accurate), and then renders the newly calculated state to the UI.

Now I noticed that when I pushed this process to its limit, I see only 50%
load. That's OKsince in theory this application is executing on only one
thread and my CPU has two cores. I wanted to see if I could get more
performance, so I've been playing around with using both a BackgroundWorker
and a normal Thread to run the non-UI part of the phsyics engine. In both
cases, on a timer tick, if the thread is not busy the UI renders, then tells
the thread to continue calculating by stepping forward by a certain
timespan.

OK this is the part that I don't get. When I use a separate thread,
performance goes DOWN, and processor utilization goes DOWN. I see the CPU
core usage flip, but the total processor usage maxes out at around 47%,
lower than the 50% I see with a single thread. So I'm looking at how both
cores are being used a little more closely... I was expecting to see one
processor maxed out, and the other nearly idle. Not so! In both the single
and multi-threaded model, I get 1/4 usage with one core and 3/4 usage with
the other. I'm starting to suspect that there aren't really two 'cores' in
the sense that I can get double the processing power of 50%.

I'm just getting into performance computing and not very versed in
multithreading yet, could anyone lend me some insight?

Thanks,
Paul
 
A

Armin Zingler

PJ6 said:
I'm pushing my CPU to its limit with a realtime physics simulation
to learn more about coding for performance. In the simplest case, I
have a form that, on a timer tick, drives the physics model forward
by the time elapsed since the last tick measured by a stopwatch
(since both the timer and DateTime.Now is not accurate), and then
renders the newly calculated state to the UI.

Now I noticed that when I pushed this process to its limit, I see
only 50% load. That's OKsince in theory this application is
executing on only one thread and my CPU has two cores. I wanted to
see if I could get more performance, so I've been playing around
with using both a BackgroundWorker and a normal Thread to run the
non-UI part of the phsyics engine.

Both for the non-UI part? And rendering also in the main (UI) thread?
In both cases, on a timer tick,

Which kind of Timer? There are three.
if the thread is not busy the UI renders, then tells the thread to
continue calculating by stepping forward by a certain timespan.

How do you detect whether a thread i busy, and which thread?
OK this is the part that I don't get. When I use a separate thread,
performance goes DOWN, and processor utilization goes DOWN. I see
the CPU core usage flip, but the total processor usage maxes out at
around 47%, lower than the 50% I see with a single thread. So I'm
looking at how both cores are being used a little more closely... I
was expecting to see one processor maxed out, and the other nearly
idle. Not so! In both the single and multi-threaded model, I get 1/4
usage with one core and 3/4 usage with the other. I'm starting to
suspect that there aren't really two 'cores' in the sense that I can
get double the processing power of 50%.

I'm just getting into performance computing and not very versed in
multithreading yet, could anyone lend me some insight?

I am not able to (intellectually) reproduce the numbers, however, the first
thing I'd change is not acting on a Timer's tick/elapsed event. If you want
full CPU usage, do the calculations in two additional threads each running
in endless loops. How to update the UI depends on how often you want it to
be updated. You can do it in the main (UI) thread, either whenever a Timer
ticks or in an endless loop, too. If rendering has such a high priority
(meaning importance, not the Thread property) that it consumes 50% CPU power
(100% of one core), only one simulation thread would be sufficient too,
because three things running on two cores don't make anything faster; just
cost a little more overhead, though negligible probably in this case.


Armin
 
P

PJ6

Armin Zingler said:
Both for the non-UI part? And rendering also in the main (UI) thread?

Yes, the rendering is in the UI thread
Which kind of Timer? There are three.
System.Windows.Forms.Timer.

How do you detect whether a thread i busy, and which thread?

I was not using both the BackGroundWorker and a normal Thread at once, I was
testing each as separate possibilities. BackGroundWorker is easy - the
IsBusy property. But I dumped that in favor of using a plain old Thread,
just use a boolean that the UI reads and the worker thread writes.
I am not able to (intellectually) reproduce the numbers, however, the
first thing I'd change is not acting on a Timer's tick/elapsed event.

Yes, I see that now. A endless loop that either idles if it's done with its
work, or computes when its not. I was doing it wrong, and the worker thread
was not running again until the rendering was complete... and I just found
out I also needed to retrieve a memberwise clone of the displayed objects'
information otherwise they get rendered while they are being processed,
which doesn't work in a scheduler model.

I finally got the CPU to hit100% by having the idler on the worker thread
check very often if there was work ready yet, and also maximizing my display
form (since GDI+ is not hardware accelerated). Now if I can figure out how
to split the physics engine's work into two threads, I can nearly double the
performance if I keep the rendering overhead low, maybe by moving to
DirectX.

Thanks!
Paul
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top