C# Multithreading on dual machine problem

G

Guest

Hi all,

In my code I have a bottleneck which consists of a cpu-intensive loop of
size LENGTH. What I did was to divide that loop into two threads, Thread1
doing the 0 to LENGTH/2 part, and Thread2 doing the LENGTH/2 to LENGTH part.
There is no synchronization between threads, so they should work pretty
freely.

My machine has two processors (dual P3, Windows 2003 server). Now comes the
problem: when running the program, both threads are scheduled on the *same*
processor! I checked many things, for example:

1) Added a while(true); infinite loop, and it resulted in each thread be
scheduled to another processor (this was a test of course, I don't need an
infinite loop!).

2) Added the following code the loops in each thread:
for (int i = 0; l < 10000000; i++);
Just an empty loop that wastes CPU. Strangely enough, this somehow signals
to the scheduler that the threads are cpu-intensive and so each thread is
scheduled on different processor.

I would like to mention again that even without this wasteful loop each
thread is already 100% cpu-intensive, and so it is very strange that the
scheduler does not assign each thread to seperate processor.

As a last resort, I tried using a Win API call to SetThreadAffinityMask to
manually assign each thread to seperate processor. This to no avail, as my
request was ignored! (although the SetThreadAffinityMask function did not
return a fail status.) Again, strangely enough, when I use
SetThreadAffinityMask in the while(true) example above to ask the scheduler
to assign both threads to same processor, the scheduler does respect the
request and assigns both threads to same processor.

Finally, I have to mention that within the loops many memory accesses are
done (though no memory allocations). Is it possible that because of this the
scheduler places both threads on same processor to share L1 cache? (Though
after many years of parallel programming in C/C++ I have never encountered
such a strange behavior).

And if not, is it possible that the problem is because of a bug in .NET
Framework thread handling?

Thanks in advance for any reply that might shed some light on this mystery.
 
J

John Bailo

David said:
Hi all,

In my code I have a bottleneck which consists of a cpu-intensive loop of
size LENGTH. What I did was to divide that loop into two threads, Thread1
doing the 0 to LENGTH/2 part, and Thread2 doing the LENGTH/2 to LENGTH part.
There is no synchronization between threads, so they should work pretty
freely.

My machine has two processors (dual P3, Windows 2003 server). Now comes the
problem: when running the program, both threads are scheduled on the *same*
processor! I checked many things, for example:

That doesn't sound odd at all. The point of threads is simply to allow
processes to run without blocking each other. The same amount of CPU
is utilized, it's just divvy'd up between the threads. If the first
processor has enough juice to run both threads, than so be it.
 
G

Guest

John Bailo said:
That doesn't sound odd at all. The point of threads is simply to allow
processes to run without blocking each other. The same amount of CPU
is utilized, it's just divvy'd up between the threads. If the first
processor has enough juice to run both threads, than so be it.

Impossible. Each of the two threads if run alone would already consume 100%
cpu, so it is not possible that "the first processor has enough juice to run
both threads."
 
J

John Bailo

David said:
Impossible. Each of the two threads if run alone would already consume 100%
cpu, so it is not possible that "the first processor has enough juice to run
both threads."

A while loop that does an increment wouldn't use up a processor.

It's not cumulative.

It's using a little slice of CPU time/ /per/ /second/ with each
increment of the register.
 
D

David

-----Original Message-----


A while loop that does an increment wouldn't use up a processor.

It's not cumulative.

It's using a little slice of CPU time/ /per/ /second/ with each
increment of the register.

What does the while loop have to do with the question?
Each of my 2 threads perform a cpu-intensive task (e.g.,
many mathematical calculations, etc) that take several
minutes to complete.

When running 2 threads in parallel, each of them should be
assigned to another processor, which would result in
almost 50% reduction in total time spent (as there are no
synchronizatin points to delay the threads' calculations).
But instead, both are scheduled on same processor, not
taking benefit of the second processor.

P.S. While I appreciate your reply, I have to mention that
I am not new to parallelism (based on your replies, you
have assume that). I have spent many years on parallel
programming with C/C++, both on SMP machine and NUMA
supercomputers. My question is *NOT* about parallelism,
but about *.NET* handling of threads. Again, thanks in
advance for any reply that would shed light on why .NET
messes up the threads.
 
W

Willy Denoyette [MVP]

David said:
What does the while loop have to do with the question?
Each of my 2 threads perform a cpu-intensive task (e.g.,
many mathematical calculations, etc) that take several
minutes to complete.

When running 2 threads in parallel, each of them should be
assigned to another processor, which would result in
almost 50% reduction in total time spent (as there are no
synchronizatin points to delay the threads' calculations).
But instead, both are scheduled on same processor, not
taking benefit of the second processor.

P.S. While I appreciate your reply, I have to mention that
I am not new to parallelism (based on your replies, you
have assume that). I have spent many years on parallel
programming with C/C++, both on SMP machine and NUMA
supercomputers. My question is *NOT* about parallelism,
but about *.NET* handling of threads. Again, thanks in
advance for any reply that would shed light on why .NET
messes up the threads.

..NET doesn't messes up the threads, it doesn't even handle thread
scheduling, .NET is at the mercy of the OS scheduler for this just like any
other kind of application running on windows.
It's hard to tell what's going on without seeing any code, also we need more
info on the context of the application, things like the type of application
(console, windows...), number of threads and their priorities, the math
classes you are using (pure framework or other native) are a minimum to
start with.

All I can say for now, based on your problem description (the load is spread
over the available CPU's when executing a simple loop in parallel, but it's
serialized when calling into a math library ) is that the math library is
holding a lock effectively preventing the other thread to run in parallel.

Willy.
 
Q

QWERTY

Did you try putting some of your code into the loop one at a time and
see which line causes the thread to go sequentially?
 

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