Being the method fork(); within compute() how come that does not get called another degree of parallelism each time the method compute() occurs? Is there a boolean flag perhaps?
EDIT:
overriding the method compute() of the class RecursiveTask:
(pseudocode)
if {array.length<100)
do it
else
divide array by 2;
fork();
int righta = rightArray.compute();
int lefta =(Integer)leftArray.join();
return righta +lefta;
So basically this is the compute() method which gets called recursively and when fork() happens it makes it possible to use parallelism and process that task with another core. However being recursive fork() should be called all the times the method gets recursively called. So in the reality it does not happen (there would be no sense). Is it due to a boolean flag that says fork has already been activated?
Thanks in advance.
Look at the API
class Fibonacci extends RecursiveTask<Integer> {
final int n;
Fibonacci(int n) { this.n = n; }
Integer compute() {
if (n <= 1)
return n;
Fibonacci f1 = new Fibonacci(n - 1);
f1.fork();
Fibonacci f2 = new Fibonacci(n - 2);
return f2.compute() + f1.join();
}
}
Each time compute() is called it will place another computation on another thread (or queue) via fork. compute continuously forks until there are no more n available to process. At this point compute will wait until the "right" side finishes while f1.join() waits for the "left" side to finish.
Whenever join is invoked it will actually make the joining thread execute lower level tasks (lower on the binary tree) giving you the parallelism you want
Related
I have a program that applies median filtering to elements in an array. I'm using divide-and-conquer with Java's Fork/Join Framework to accomplish this. Here's my compute() override:
public FilterObject(int lo, int hi, boolean filterType)
{
this.lo = lo;
this.hi = hi;
this.filterType = filterType;
}
public void compute()
{
if (hi - lo <= SEQUENTIAL_THRESHOLD)
{
seqFilter();
}
else
{
FilterObject left = new FilterObject(lo, (hi + lo) / 2, filterType);
FilterObject right = new FilterObject((hi + lo) / 2, hi, filterType);
left.fork();
right.compute();
left.join();
}
}
seqFilter() is a static method that does the actual filtering once a subarray is "small enough".
Is my join() in the right place? I have a timer running in my Main class and the recorded times I'm getting seem way too fast. I'm calling pool.invoke(filt)from my Main class where filt is my FilterObject object and pool is my ForkJoinPool. My timer stops immediately after this call. Is it possible that the main logic is continuing on before the parallel processes have completed? If it is, where can I put join() to stop this happening?
EDIT: Additional question - do I even need the join() in this case? The program forks, but it's not like I actually 'join' my forked objects together again because the recursive split index references just get and set from the same arrays.
So I have this multithreadded program that generates 2 random walkers, each walker is a separate thread since I need them to move simultaneously. Each walker randomly moves in any of the 4 directions. The first problem is that i think stdDraw is not thread safe and therefore without having a lock around my entire function, it tends to draw random squares at random points for no reason and the whole thing become pretty glitchy. When i put a lock around my function then one thread becomes slower that the other since it sometimes has to wait for the lock. So the threas are not simultaneous anymore. Is there a solution to this? The other problem i have is I want it to break out of the loop when the two walkers intersect, but for some reason the two threads dont know about the position of the other. One thinks that the position of the other is always at (0,0). Thanks!
import java.awt.Color;
public class WalkerThread implements Runnable {
String name;
static Integer lock = new Integer(1000);
int num;
static int steps = 0, steps2 = 0;
static int x = 0, y = 0;
static int x2 = -1, y2 = -2;
public WalkerThread(String s, int n) {
this.name = s;
this.num = n;
}
#Override
public void run() {
int N = 10;
StdDraw.create(600, 600);
StdDraw.setScale(-N, -N, +N, +N);
StdDraw.clear(Color.gray);
do {
synchronized (lock) {
if (num == 1) {
StdDraw.go(x, y);
StdDraw.setColor(Color.white);
StdDraw.spot(0.9, 0.9);
double r = Math.random();
if (r < 0.25)
x--;
else if (r < 0.50)
x++;
else if (r < 0.75)
y--;
else if (r < 1.00)
y++;
steps++;
StdDraw.setColor(Color.blue);
StdDraw.go(x, y);
StdDraw.spot(0.9, 0.9);
StdDraw.pause(40);
}
if (num == 2) {
StdDraw.go(x2, y2);
StdDraw.setColor(Color.yellow);
StdDraw.spot(0.9, 0.9);
double r2 = Math.random();
if (r2 < 0.25)
x2--;
else if (r2 < 0.50)
x2++;
else if (r2 < 0.75)
y2--;
else if (r2 < 1.00)
y2++;
steps2++;
StdDraw.setColor(Color.green);
StdDraw.go(x2, y2);
StdDraw.spot(0.9, 0.9);
StdDraw.pause(40);
}
}// lock
/*String pict = steps + ".png";
StdDraw.save(pict);*/
//if (posX == posX2 && posY == posY2) break;
} while ((Math.abs(x) < N && Math.abs(y) < N) && (Math.abs(x2) < N && Math.abs(y2) < N));
System.out.printf("Total steps of %s is %d and %d \n", name, steps, steps2);
}
}
//MAIN
public class Walkers{
public static void main(String[] args) {
Thread t1 = new Thread(new WalkerThread("one", 1));
Thread t2 = new Thread(new WalkerThread("two", 2));
t1.start();
t2.start();
}
}
Avoid Math.random() when going multi-threaded - create an r = new Random() in your Walker constructor, and use it as r.nextDouble().
Instead of the big if, take the differences between both branches (just a couple of colors) and place them in the constructor. Also, threads have separate namespaces. You don't need to keep x and x2 separate - each thread would have its own private x, invisible from the other thread. Your code could roughly end up 1/2 the size.
As far as synchronization goes, you have two problems. The first problem is that StdDraw is built on Swing (it runs in a JFrame, for example), which is not thread-safe. In particular, all drawing must happen in something called the event thread. This means that you should place all the drawing code within something like
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
synchronized (lock) {
// ... your calls to StdDraw here ...
}
}
});
However, this opens a big can of worms. First, the drawing code needs to access your data, which you will therefore want to prevent from changing at the same time. You can protect it with yet more synchronized (lock) { ... }, but that will mean that only one thread will be executing in any given moment. That's not what multithreading is for.
The simpler answer is, taking a peek at Elyasin's answer, to forget about parallel execution (it is really not needed here), and embrace turn-taking:
do {
bool turn = false;
// ... current init code here
if (turn) {
// ... current code for num==1
} else {
// ... current code for num==2
}
turn = !turn; // reverse turn for next round
} while (/* ... */);
No threads, no locks, no synchronization, and it should work smoothly and without artifacts.
So I have this multithreaded program that generates 2 random walkers,
each walker is a separate thread since I need them to move
simultaneously. Each walker randomly moves in any of the 4 directions.
You clearly state that you want two random walkers, any of the four directions is chosen randomly by any of the two walkers. So we stick to this requirement.
The first problem is that I think stdDraw is not thread safe and
therefore without having a lock around my entire function it tends to
draw random squares at random points for no reason and the whole thing
becomes pretty glitchy. When I put a lock around my function then one
thread becomes slower than the other one, since it sometimes has to wait
for the lock. So the threads are not simultaneous anymore. Is there a
solution to this?
Thread safety and randomness are not really correlated here. As clarified above you want the walkers to be random. This has nothing to with thread safety in the first place. Simply put: Thread safety means that if several threads share a data structure/address space, then access to it is guaranteed to be free of race conditions.
Not sure what you mean with random squares at random points for no reason. A lock is usually used to grant permissions to execute, or to grant access to one or more shared resources. Not sure why you use a lock here, I don't see a shared resource and I don't see why you use the lock to control thread execution one at a time if you don't want this in the first place.
The two random walkers are independent and the only shared resource I see is the 2D plane.
If you want the two walkers to execute simultaneously/concurrently then you should not use a lock the way you did I think.
I am not even sure if thread safety really is an issue here, maybe you don't need thread safety?
The other problem I have is I want it to break out of the loop when
the two walkers intersect, but for some reason the two threads don't
know about the positions of each other. One thinks that the position of
the other one is always at (0,0).
Oh, now that is a good follow up question. Maybe there is a shared resource then? Will it have to be thread safe then?
That is the 2D plane, which would know if the two walkers intersect or not? (I did not look into the StdDraw to be honest, but you would know to find out I think.) Find a way to get the two coordinates of the two random walkers from the StdDraw and check for intersection. If that is not possible then use a shared resource, i.e. a data structure that holds both coordinates of 1st random walker and 2nd random walker.
You would not need to care much about thread safety, because one random walker would only read (and not write) the values/coordinates of the other random walker.
Try that out and let us know.
I'm trying to convert this code to java and using thread to implement it
turn = 0 // shared control variable
while (turn != i);
// CS
turn = (turn + 1) % n;
I'm really tried hard to reach to right code but I failed this is my code
/*
* Mutual exclusion using thread
*/
class gV{
int turn=0;
}
class newThread extends Thread{
static int i;
int n=10;
newThread(gV obj){
this.i=obj.turn;
start();
}
public void run(){
while(obj.turn!=i&&obj.turn<n);
criticalSection(i);
obj.turn=(obj.turn+1);
i++;
}
public void criticalSection(int numOfProcess){
System.out.println("Process " + numOfProcess + " done!!");
}
}
class MutualExclusion{
public static void main(String args[]){
gV obj = new gV();
new newThread(obj);
}
}
I know my code has some mistakes. Thank you for the help!
Use an AtomicInteger.
Atomic means that any operation on it will fully complete before any other thread can see the result. Meaning that you won't have two simultaneous operations 'clobber' it. For example, imagine if you had a non atomic integer and two threads attempted to increment it simultaneously - say it had value 1, they both read it as 1 and attempt to set it to 2. They both incremented it once - but instead of it becoming 3, it became 2! AtomicInteger solves this problem by giving you IncrementAndGet, which guarantees no other thread can access the AtomicInteger's value before the increment completes.
In particular, use these methods:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html#get()
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html#incrementAndGet()
You might notice that this increments it, but it doesn't take it modulo n. Well, you can take it modulo n whenever you read its value, you don't need it to be stored that way.
EDIT: By the way, doing something like this:
while (turn != i);
is called busy-waiting, and it's a bad idea because it means that CPU usage will be 100%, checking the variable hundreds of thousands of times per second. In this kind of scenario, instead of making each thread check as often as possible, you want to have threads wait and be notifyed by another thread when it is that thread's turn to continue execution.
I believe in Java that using lock and synchronized to implement mutual exclusion will also give you this property, e.g. if you try to lock on something or enter a synchronized block but it is already in use then the thread goes to sleep and is woken up when it is its turn. So, you can look into this as well.
I have a simple recursive method, a depth first search. On each call, it checks if it's in a leaf, otherwise it expands the current node and calls itself on the children.
I'm trying to make it parallel, but I notice the following strange (for me) problem.
I measure execution time with System.currentTimeMillis().
When I break the search into a number of subsearches and add the total execution time, I get a bigger number than the sequential search. I only measure execution time, no communication or sync, etc. I would expect to get the same time when I add the times of the subtasks. This happens even if I just run one task after the other, so without threads. If I just break the search into some subtasks and run the subtasks one after the other, I get a bigger time.
If I add the number of method calls for the subtasks, I get the same number as the sequential search. So, basically, in both cases I do the same number of method calls, but I get different times.
I'm guessing there's some overhead on initial method calls or something else caused by a JVM mechanism. Any ideas what could it be?
For example, one sequential search takes around 3300 ms. If I break it into 13 tasks, it takes a total time of 3500ms.
My method looks like this:
private static final int dfs(State state) {
method_calls++;
if(state.isLeaf()){
return 1;
}
State[] children = state.expand();
int result = 0;
for (int i = 0; i < children.length; i++) {
result += dfs(children[i]);
}
return result;
}
Whenever I call it, I do it like this:
for(int i = 0; i < num_tasks; i++){
long start = System.currentTimeMillis();
dfs(tasks[i]);
totalTime += (System.currentTimeMillis() - start);
}
Problem is totalTime increases with num_tasks and I would expect to stay the same because the method_calls variable stays the same.
You should average out the numbers over longer runs. Secondly the precision of currentTimeMillis may not be sufficient, you can try using System.nanoTime().
As in all the programming languages, whenever you call a procedure or a method, you have to push the environment, initialize the new one, execute the programs instructions, return the value on the stack and finally reset the previous environment. It cost a bit! Create a thread cost also more!
I suppose that if you enlarge the researching tree you will have benefit by the parallelization.
Adding system clock time for several threads seems a weird idea. Either you are interested in the time until processing is complete, in which case adding doesn't make sense, or in cpu usage, in which case you should only count when the thread is actually scheduled to execute.
What probably happens is that at least part of the time, more threads are ready to execute than the system has cpu cores, and the scheduler puts one of your threads to sleep, which causes it to take longer to complete. It makes sense that this effect is exacerbated the more threads you use. (Even if your program uses less threads than you have cores, other programs (such as your development environment, ...) might).
If you are interested in CPU usage, you might wish to query ThreadMXBean.getCurrentThreadCpuTime
I'd expect to see Threads used. Something like this:
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Puzzle {
static volatile long totalTime = 0;
private static int method_calls = 0;
/**
* #param args
*/
public static void main(String[] args) {
final int num_tasks = 13;
final State[] tasks = new State[num_tasks];
ExecutorService threadPool = Executors.newFixedThreadPool(5);
for(int i = 0; i < num_tasks; i++){
threadPool.submit(new DfsRunner(tasks[i]));
}
try {
threadPool.shutdown();
threadPool.awaitTermination(1, TimeUnit.SECONDS);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println(method_calls + " Methods in " + totalTime + "msecs");
}
static final int dfs(State state) {
method_calls++;
if(state.isLeaf()){
return 1;
}
State[] children = state.expand();
int result = 0;
for (int i = 0; i < children.length; i++) {
result += dfs(children[i]);
}
return result;
}
}
With the runnable bit like this:
public class DfsRunner implements Runnable {
private State state;
public DfsRunner(State state) {
super();
this.state = state;
}
#Override
public void run() {
long start = System.currentTimeMillis();
Puzzle.dfs(state);
Puzzle.totalTime += (System.currentTimeMillis() - start);
}
}
Just wondering if anyone would be able to take a look at this code for implementing the quicksort algorithm and answer me a few questions, please :-)
public class Run
{
/***************************************************************************
* Quicksort code from Sedgewick 7.1, 7.2.
**************************************************************************/
public static void quicksort(double[] a)
{
//shuffle(a); // to guard against worst-case
quicksort(a, 0, a.length - 1, 0);
}
static void quicksort(final double[] a, final int left, final int right, final int tdepth)
{
if (right <= left)
return;
final int i = partition(a, left, right);
if ((tdepth < 4) && ((i - left) > 1000))
{
final Thread t = new Thread()
{
public void run()
{
quicksort(a, left, i - 1, tdepth + 1);
}
};
t.start();
quicksort(a, i + 1, right, tdepth + 1);
try
{
t.join();
}
catch (InterruptedException e)
{
throw new RuntimeException("Cancelled", e);
}
} else
{
quicksort(a, left, i - 1, tdepth);
quicksort(a, i + 1, right, tdepth);
}
}
// partition a[left] to a[right], assumes left < right
private static int partition(double[] a, int left, int right)
{
int i = left - 1;
int j = right;
while (true)
{
while (less(a[++i], a[right]))
// find item on left to swap
; // a[right] acts as sentinel
while (less(a[right], a[--j]))
// find item on right to swap
if (j == left)
break; // don't go out-of-bounds
if (i >= j)
break; // check if pointers cross
exch(a, i, j); // swap two elements into place
}
exch(a, i, right); // swap with partition element
return i;
}
// is x < y ?
private static boolean less(double x, double y)
{
return (x < y);
}
// exchange a[i] and a[j]
private static void exch(double[] a, int i, int j)
{
double swap = a[i];
a[i] = a[j];
a[j] = swap;
}
// shuffle the array a[]
private static void shuffle(double[] a)
{
int N = a.length;
for (int i = 0; i < N; i++)
{
int r = i + (int) (Math.random() * (N - i)); // between i and N-1
exch(a, i, r);
}
}
// test client
public static void main(String[] args)
{
int N = 5000000; // Integer.parseInt(args[0]);
// generate N random real numbers between 0 and 1
long start = System.currentTimeMillis();
double[] a = new double[N];
for (int i = 0; i < N; i++)
a[i] = Math.random();
long stop = System.currentTimeMillis();
double elapsed = (stop - start) / 1000.0;
System.out.println("Generating input: " + elapsed + " seconds");
// sort them
start = System.currentTimeMillis();
quicksort(a);
stop = System.currentTimeMillis();
elapsed = (stop - start) / 1000.0;
System.out.println("Quicksort: " + elapsed + " seconds");
}
}
My questions are:
What is the purpose of the variable tdepth?
Is this considered a "proper" implementation of a parallel quicksort? I ask becuase it doesn't use implements Runnable or extends Thread...
If it doesn't already, is it possible to modify this code to use multiple threads? By passing in the number of threads you want to use as a parameter, for example...?
Many thanks,
Brian
1. It's used to keep track of recursion depth. This is checked to decide whether to run in parallel. Notice how when the function runs in parallel it passes tdepth + 1 (which becomes tdepth in the called quicksort's parameters). This is a basic way of avoiding too many parallel threads.
2. Yes, it's definitely using another thread. The code:
new Thread()
{
public void run()
{
quicksort(a, left, i - 1, tdepth + 1);
}
};
creates an anonymous inner class (which extends Thread), which is then started.
Apparently, tdepth is used to avoid creating too many threads
It uses an anonymous class, which implicitly extends Thread
It does that already (see point 1.)
tdepth is there so that there's an upper bound on the number of threads created. Note that ever time the method calls itself recursively (which is done in a new thread), tdepth is incremented by one. This way, only the first four levels of recursion will create new threads, presumably to prevent overloading the OS with many threads for little benefit.
This code launches its own threads in the definition of the quicksort method, so it will use parallel processing. One might argue that it could do with some kind of thread management and that e.g. some kind of Executor might be better, but it is definitely parallel. See the call to new Thread() ... followed by start(). Incidentally, the call to t.join() will cause the current thread to wait for the thread t to finish, in case you weren't aware of that.
This code already uses multiple threads, but you can tweak how many it spawns given the comparison on tdepth; increasing or decreasing the value will determine how many levels of recursion create threads. You could complete rewrite the code to use executors and threadpools, or perhaps to perform trinary recursion instead of binary - but I suspect that in the sense you asked; no, there's no simple way to tweak the number of threads.
I did actually wrote a (correctly) multi-threaded QuickSort in Java so maybe I can help a bit...
Question here for anyone interested:
Multithreaded quicksort or mergesort
What is the purpose of the variable
tdepth?
as other have commented, it serves to determine whether to create new threads or not.
Is this considered a "proper"
implementation of a parallel
quicksort? I ask because it doesn't
use implements Runnable or extends
Thread...
I don't think it's that proper for several reasons: first you should make it CPU dependent. There's no point in spawning 16 threads on a CPU that has just one core: a mono-threaded QuickSort shall outperfom the multi-threaded one on a single core machine. On a 16-cores machines, sure, fire up to 16 threads.
Runtime.getRuntime().availableProcessors()
Then the second reason I really don't like it is that it is using last-century low-level Java idiosyncrasish threading details: I prefer to stay away from .join() and use higher level things (see fork/join in the other question or something like CountDownLatch'es, etc.). The problem with things low-level like Java's thread "join" is that it carries no useful meaning: this is 100% Java specific and can be replaced by higher-level threading facilities whose concept are portable across languages.
Then don't comment the shuffle at the beginning. Ever. I've seen dataset where QuickSort degrades quadratically if you remove that shuffle. And it's just an O(n) shuffle, that won't slow down your sort :)
If it doesn't already, is it possible
to modify this code to use multiple
threads? By passing in the number of
threads you want to use as a
parameter, for example...?
I'd try to write and/or reuse an implementation using higher-level concurrency facilities. See the advices in the question I asked here some time ago.