A question about multithreading

T

Ted

I managed to get my threading script to work, to a point. I can
launch an arbitrary number of threads, and have them run
concurrently. But the processor is not being fully exploited. If I
launch ONE child process in one thread, one of the four available
cores is nearly fully utilized (about 95% of that one core's cycles.
But if I launch four, the load is distributed evenly over ALL
available cores, but only about 5% of the processor's capacity is
used This means that the time I have to wait for results is twnety
times longer than it would be if I could get the processor fully
utilitized! WHY? Might it have something to do with thread priority?

If I launch the same four child processes manually, each in its own
separate commandline window, then I get the processor being fully
utilized. How do I get the same effect by launching threads or child
processes? But this gets quite tedious very quickly when there are
dozens of scripts to run!

Any suggestions would be appreciated.

Thanks

Ted
 
J

Joost Diepenmaat

Ted said:
If I launch ONE child process in one thread, one of the four available
cores is nearly fully utilized (about 95% of that one core's cycles.

This is ofcourse expected.
But if I launch four, the load is distributed evenly over ALL
available cores, but only about 5% of the processor's capacity is
used This means that the time I have to wait for results is twnety
times longer than it would be if I could get the processor fully
utilitized! WHY? Might it have something to do with thread priority?

Since I can't see your code, I would assume this is because of the usual
cause: the threads are actually waiting on some external even like IO to
finish before they can contintue.

If your code is actually badly written, I would suspect your threads are
locking each other out.
If I launch the same four child processes manually, each in its own
separate commandline window, then I get the processor being fully
utilized. How do I get the same effect by launching threads or child
processes? But this gets quite tedious very quickly when there are
dozens of scripts to run!

So your threads aren't sharing any data and run faster as separate
processes? use fork() instead. It may be more efficient anyway, Or show
your code.
 
B

Ben Morrow

Quoth Ted said:
I managed to get my threading script to work, to a point. I can
launch an arbitrary number of threads, and have them run
concurrently. But the processor is not being fully exploited. If I
launch ONE child process in one thread, one of the four available
cores is nearly fully utilized (about 95% of that one core's cycles.
But if I launch four, the load is distributed evenly over ALL
available cores, but only about 5% of the processor's capacity is
used This means that the time I have to wait for results is twnety
times longer than it would be if I could get the processor fully
utilitized! WHY? Might it have something to do with thread priority?

If I launch the same four child processes manually, each in its own
separate commandline window, then I get the processor being fully
utilized. How do I get the same effect by launching threads or child
processes? But this gets quite tedious very quickly when there are
dozens of scripts to run!

Forget threads. They really aren't helping, and are just making things
more complicated. Just start the processes in the background, using
system 1, "...", or Win32::process, or IPC::Run, or something else
equivalent. If necessary you should be able to start a new command
window for each process with something like system 'start cmd /c "..."'.

After that, you need to look at how your OS schedules processes, which
is probably off-topic for this group. Is there some sort of limit on the
total processor usage of a single process group (or whatever Win32 calls
it: I think it's a 'Job'?)? If so you may be able to get around this
with Win32::Job. Are you able to write a single batch file which invokes
several processes simultaneously (IIRC recent versions of cmd support
the '... &' syntax to run a process in the background)? Does that have
the same effect? If it doesn't, there may be something about the way
perl runs processes that's causing a problem, but I'd only consider that
option as a last resort.

Ben
 
X

xhoster

Ted said:
I managed to get my threading script to work, to a point. I can
launch an arbitrary number of threads, and have them run
concurrently. But the processor is not being fully exploited. If I
launch ONE child process in one thread, one of the four available
cores is nearly fully utilized (about 95% of that one core's cycles.
But if I launch four, the load is distributed evenly over ALL
available cores, but only about 5% of the processor's capacity is
used This means that the time I have to wait for results is twnety
times longer than it would be if I could get the processor fully
utilitized! WHY? Might it have something to do with thread priority?

If I launch the same four child processes manually, each in its own
separate commandline window, then I get the processor being fully
utilized.

Just one processor fully utilized, or all of them fully utilized?

Is exactly the same work being accomplished via both methods? For example,
is one method running task A four times but the other is running tasks A,
B, C, and D?
How do I get the same effect by launching threads or child
processes? But this gets quite tedious very quickly when there are
dozens of scripts to run!

Any suggestions would be appreciated.

Create a script that fires off other scripts using whatever method is best
suited to your OS, and stop screwing around with threads.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
T

Thomas Kratz

Ted said:
If I launch the same four child processes manually, each in its own
separate commandline window, then I get the processor being fully
utilized. How do I get the same effect by launching threads or child
processes? But this gets quite tedious very quickly when there are
dozens of scripts to run!

I suspect Joost is right in suspecting IO might be the problem.
Since ou mention a "commandline window", are you generating output to
the same terminal from each thread? If so, this could be the bottleneck.
In the example code below you can play around with the amount of output
send to the terminal. On my machine going below 2000 will show the
effect you are describing.

use strict;
use warnings;
use threads;

my $counter = 0;
my $print_interval = $ARGV[0] || 10000;

sub adder {
my $tid = threads->self()->tid();
while (1) {
$counter++;
if ( $counter % $print_interval == 0 ) {
print "Hi! from thread $tid\n";
}
}
}

threads->new(\&adder)->detach() for 1 .. 4;

while (1) { sleep 1 }

--
$/=$,,$_=<DATA>,s,(.*),$1,see;__END__
s,^(.*\043),,mg,@_=map{[split'']}split;{#>J~.>_an~>>e~......>r~
$_=$_[$%][$"];y,<~>^,-++-,?{$/=--$|?'"':#..u.t.^.o.P.r.>ha~.e..
'%',s,(.),\$$/$1=1,,$;=$_}:/\w/?{y,_, ,,#..>s^~ht<._..._..c....
print}:y,.,,||last,,,,,,$_=$;;eval,redo}#.....>.e.r^.>l^..>k^.-
 
T

Ted

This is ofcourse expected.


Since I can't see your code, I would assume this is because of the usual
cause: the threads are actually waiting on some external even like IO to
finish before they can contintue.

If your code is actually badly written, I would suspect your threads are
locking each other out.


So your threads aren't sharing any data and run faster as separate
processes? use fork() instead. It may be more efficient anyway, Or show
your code.
That is right. Using system 1, "cmd ..." did the trick.

All the real computing is done in stored procedures. The only
difference between one SQL script and the next is that they pass
different data to the same stored procedures.

But two questions remain. Do threads launched by a process get the
same priority as the process, or are they given lower priority. And,
one commonality in how I was launching the SQL scripts was that the
script was invoked taking the script from one file and sending the
output (from standard out) into another file. Would the threads be
sharing standard out making each other wait to output their data to
their respective files?

Thanks

Ted
 

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

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,905
Latest member
Kristy_Poole

Latest Threads

Top