Adding Threads to a Sequential Program help!

D

D Jensen

Hi,
A basic thread question that i can't seem to find an answer to in the
faqs:
The question is how to run a METHOD as a thread... situation is below:

I've written a MonteCarlo simulation program in Java (with minimal use
of object oriented principles -- i have to run through the simulation
about 5 million times, and the overhead that would be caused by
creating/modifying a few hundred objects per time would be
unacceptable).
It will only be used on Intel processors with HT, so i really want to
be able to use 2 threads, each doing the simulation 2.5 million times,
and then averaging the results. Right now, it's entirely a CLI program
(though a GUI would be trivial to add).

It's almost entirely sequentially oriented (as opposed to OO)
The basic outline of my program is as follows:
4 classes (for clarity purposes only -- none is ever instantiated as an
object):
1) ArrayFunc - contains optimized (for my purposes) copy methods for 1d
and 2d arrays, as well as methods for removing an element from an array
by index or value, "casting" an array of floats to ints, etc.

2) Interact - contains all the methods needed to get values from the
user, with error checking & exception handling

3) TestFor - contains about 65 methods operating on various sizes of
various dimension arrays that are needed for the simulation - often
calls methods in ArrayFunc

4) Simulator - the only class with a main() method, contains an
initialization method (as opposed to a constructor, as an object is
never created), as well as all the calls to the various methods; a
doSimulation() method, which runs through the simulation 5 million
times, each time incrementing a "winner" in an array before dividing
all elements of the winner-array by 5M, and printing out the output.

Fundamentally, then, what I want to do is run doSimulation twice (each
2.5M times), in separate threads, so that they run concurrently. After
a little experimentation, this seems (to me) to translate into putting
it into a separate class, making that class runnable, and putting it
all into the run() method of that new class. That seems a lot of
wierdness for just wanting to run one single method twice
concurrently... Any way to do this without creating actual objects? Any
help? (and yes, this is my first time trying to implement threads in a
non-trivial exercize). If someone might post a program that would
create a few random numbers and average them, twice in 2 threads, that
would probably solve my entire problem (i'd be able to work backwards,
i think)

Many thanks for any ideas!
if my explanation was too convoluted, i'll post the barebones of my
classes somewhere if that would help. THANKS!


David Jensen
EPFL, Switzerland


PS. on a 3.4GHz pentium4 running WinXP, the program as it currently is
takes around 110s to run, but task manager shows only 50% of the CPU is
being used (though the graphs in task manager show both being used
around 50%) -- if i could get it down to around 60 or 65 seconds, that
would be great, and is the main reason for me wanting to use 2 threads.
PPS. yes, the variance is so ridiculous that i DO need to run it 5M
times.
 
H

Harald

D Jensen said:
Hi,
A basic thread question that i can't seem to find an answer to in the
faqs:
The question is how to run a METHOD as a thread... situation is below:

Sorry, I did not read the rest of your loooooong post. If your method
has parameters and a return value, e.g.

ResultType m(String s, int i)

then add a parameterization method to the class like

void setParamsForM(String s, int i) {
this.s = s;
this.i = i;
}

Then write a run() like this:

public void run() {
this.resultOfM = null;
this.runException = null;
try {
this.resultOfM = m(this.s, this.i);
} catch( Exception e ) {
this.runException = e;
}

Now create on object of our class, stuff it in a thread and start the
thread.

MyObj mo = new MyObj();
mo.setParamsForM("blar", 10);
new Thread(mo).start();
if( mo.runException!=null ) {
throw new Exception("thread fell over", mo.runException);
}
System.out.println("Result is: "+mo.resultOfM);

You specific implementation may differ, but you get the idea.

Harald.
 
J

John C. Bollinger

D Jensen wrote:

[...]
4) Simulator - the only class with a main() method, contains an
initialization method (as opposed to a constructor, as an object is
never created), as well as all the calls to the various methods; a
doSimulation() method, which runs through the simulation 5 million
times, each time incrementing a "winner" in an array before dividing
all elements of the winner-array by 5M, and printing out the output.

Fundamentally, then, what I want to do is run doSimulation twice (each
2.5M times), in separate threads, so that they run concurrently. After
a little experimentation, this seems (to me) to translate into putting
it into a separate class, making that class runnable, and putting it
all into the run() method of that new class. That seems a lot of
wierdness for just wanting to run one single method twice
concurrently... Any way to do this without creating actual objects?

Your aversion to creating objects is odd. In the first place, object
creation is generally quite cheap on modern VMs. In the second place,
you already *are* creating some objects, as arrays are objects. I can
understand not wanting to burden your program with cleaning up excessive
garbage, what with 5M iterations of your principal compute method, but I
have no clue why you want to avoid creating just two objects for each of
two threads.

Writing correct multithreaded code is difficult, and managing threads is
tricky. "[J]ust wanting to run one single method twice concurrently"
sweeps quite a lot of complication under the rug. Nevertheless, you can
probably code the basic mechanism much more easily than you seem to
think. (See below.)
Any
help? (and yes, this is my first time trying to implement threads in a
non-trivial exercize). If someone might post a program that would
create a few random numbers and average them, twice in 2 threads, that
would probably solve my entire problem (i'd be able to work backwards,
i think)

You may want something along these lines:

public class Simulator implements Runnable {

static void doSimulation() {
}

public void run() {
doSimulation();
}

public static void main(String[] args) {

// Create the Threads
Thread t1 = new Thread(new Simulator());
Thread t2 = new Thread(new Simulator());

// Start the threads
t1.start();
t2.start();

// Wait for the threads to finish
t1.join();
t2.join();

// Whatever else...

}
}


You could also create a seperate Runnable implementation class if you
wished; its basic implementation need not be particularly more
complicated than the run() method I assigned to Simulator in the example.

Do note that this completely ignores the question of storing and
accessing the results of the computations, including the necessary
synchronized access to shared data structures. If you need help in that
area then I would prefer to see some details of what you really hope to
do, rather than to give you an example that may turn out to not
adequately address your needs.
PS. on a 3.4GHz pentium4 running WinXP, the program as it currently is
takes around 110s to run, but task manager shows only 50% of the CPU is
being used (though the graphs in task manager show both being used
around 50%) -- if i could get it down to around 60 or 65 seconds, that
would be great, and is the main reason for me wanting to use 2 threads.

You should recognize that although an HT P4 looks to the OS like two
processors, it doesn't work like two. Two threads can access different
functions of the CPU simultaneously (with considerable restrictions) but
the CPU still only has one processor's worth of circuits. 50% CPU
utilization likely means 100% utilization of the parts your program
uses, and I'd bet it would show as 100% utilization if you turned HT
off. You may therefore find that a dual-threaded version performs no
better than the single-threaded version. It may even do worse. You'll
need to test it to find out.
PPS. yes, the variance is so ridiculous that i DO need to run it 5M
times.

Is variance so great to be expected for the algorithm? That could well
be, but if so then you should be sure to understand why. There are
other alternatives, such as numerical instability of your computation,
and it is at least conceivable that some of these could introduce bias
into your results.
 
N

Nigel Wade

You can't make a sequential operation run sensibly on multiple threads.
Multiple threads are used for operations which can be run in parallel.

Can your code be parallelised, and can you synchronise access to the data
which will be shared between the threads?
 
D

D Jensen

Thanks to all who helped me out, I think John Bollinger's response was
pretty much exactly what I needed... and the detailed post by him
helped me learn a bit about the internals as well. End result: yes, it
was speeded up by between 20 and 30% (depending on the exact nature of
the various inputs).
Again, many thanks (and John, i've replied personally to you as well)!

David Jensen
 
S

steve

PS. on a 3.4GHz pentium4 running WinXP, the program as it currently is
takes around 110s to run, but task manager shows only 50% of the CPU is
being used (though the graphs in task manager show both being used
around 50%) -- if i could get it down to around 60 or 65 seconds, that
would be great, and is the main reason for me wanting to use 2 threads.
PPS. yes, the variance is so ridiculous that i DO need to run it 5M
times.

AHH!!

the philosophers stone.

if it is a sequential program , it cannot be run in parallel threads.
( that is if the information you have given us is correct)

Unless each of the 5,000,000 calculations are independent of each other, (
sort of like 5,000,000 blades of grass all growing together, which is an
example of a parallel process)
or perhaps you can come up with some sort of sophisticated system , that can
do some part of the calculation in a thread, ensuring that any required
future calculation already had the source data ready, before it started.



steve
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top