I was running some tests with parallel processing and made a program that given a matrix of integers re-calcutes each position's value based on the neighbours.
I needed a copy of the matrix so the values wouldn't be overriden and used a CyclicBarrier
to merge the results once the partial problems were solved:
CyclicBarrier cyclic_barrier = new CyclicBarrier(n_tasks + 1, new Runnable() {
public void run() {
ParallelProcess.mergeResult();
}
});
ParallelProcess p = new ParallelProcess(cyclic_barrier, n_rows, r_cols); // init
Each task is assigned a portion of the matrix: I'm splitting it in equals pieces by rows. But it might happen that the divisions are not exact so there would be a small piece corresponding to the lasts row that wouldn't be submitted to the thread pool.
Example: if I have 16
rows and n_tasks = 4
no problem, all 4 will be submitted to the pool. But if I had 18
instead, the first 16 ones will be submitted, but not the last two ones.
So I'm forcing a submit if this case happens. Well, I'm not submitting actually, because I am using a fixed thread pool that I created like this ExecutorService e = Executors.newFixedThreadPool(n_tasks)
. Since all the slots in the pool are occupied and the threads are blocked by the barrier (mybarrier.await()
is called in the run
method) I couldn't submit it to the pool, so I just used Thread.start()
.
Let's go to the point. Since I need to take into consideration for the CyclicBarrier
the possibility of that chunk remaining, the number of parties must be incremented by 1.
But if this case didn't happen, I would be one party short to trigger the barrier.
What's my solution?:
if (lower_limit != n_rows) { // the remaining chunk to be processed
Thread t = new Thread(new ParallelProcess(lower_limit, n_rows));
t.start();
t.join();
}
else {
cyclic_barrier.await();
}
I feel like I am cheating when using the cyclic_barrier.await()
trick to raise the barrier by force.
Is there any other way I could approach this problem so I didn't have to do what I'm doing?