Can someone help me with this, please? I'm trying to do a matrix multiplication, using threads. This is what I have so far:
//updated
public class Multiplication {
public static final int NUM_OF_THREADS = 8;
public static final int MATRIX_SIZE = 1000;
public static void main(String args[]) throws InterruptedException {
long startTime = System.currentTimeMillis();
int MatrixA[][] = matrixGenerator();
int MatrixB[][] = matrixGenerator();
int m1rows = MatrixA.length;
int m1cols = MatrixA[0].length;
int m2cols = MatrixB[0].length;
int MatrixC[][] = new int[m1rows][m2cols];
ExecutorService pool = Executors.newFixedThreadPool(NUM_OF_THREADS);
for (int row1 = 0; row1 < m1rows; row1++) {
for (int col1 = 0; col1 < m1cols; col1++) {
pool.submit(new MultiplicationThreading(row1, col1, MatrixA, MatrixB, MatrixC));
}
}
pool.shutdown();
pool.awaitTermination(1, TimeUnit.DAYS);
long endTime = System.currentTimeMillis();
System.out.println("Calculated in "
+ (endTime - startTime) + " milliseconds");
}
public static int[][] matrixGenerator() {
int matrix[][] = new int[MATRIX_SIZE][MATRIX_SIZE];
Random r = new Random();
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
matrix[i][j] = r.nextInt(10000);
}
}
return matrix;
}
}
//I have updated the code
I get better timings now. When using 2 threads I get 1.5k milliseconds and when I use 8 threads 1.3k milliseconds
You initialize the thrd array with NUM_THREADS == 9 elements. If m1rows*m1cols exceeds that value, you will get this problem, since you attempt to create more than 9 threads and assign them to elements of the array. (You are attempting to create 50 threads).
Two solutions:
Initialize thrd = new Thread[m1rows*m1cols]
Use a List<Thread>.
Note that you won't execute the threads in parallel, because you are calling Thread.join() immediately after calling Thread.start(). This just blocks the current thread until thrd[threadcount] finishes.
Move the Thread.join() calls into a separate loop, so the threads are all started before you call join on any of them.
for (row = 0; row < m1rows; row++) {
for (col = 0; col < m1cols; col++) {
// creating thread for multiplications
thrd[threadcount] = new Thread(new MultiplicationThreading(row, col, MatrixA, MatrixB, MatrixC));
thrd[threadcount].start(); //thread start
threadcount++;
}
}
for (Thread thread : thrd) {
thread.join();
}
Related
I'm trying to multiply three matrices using threads. I use a number of threads for a matrix multiplication and I should use another number of threads for multiply the result of the two matrices with the last matrices, and I would like to start the threads for the second multiplication as soon as they start having data from the first multiplication result. I'm a little stuck.
What I've tried:
public class Threads implements Runnable{
private String action;
private int range;
public Threads(String action, int range) {
this.action = action;
this.range = range +1;
}
public synchronized void run() {
int k;
int counter = 0;
int m_size = Program.m1.length;
int k_size =Program.m1[0].length;
int n_size = Program.m2[0].length;
int h_size = Program.m3[0].length;
for (int i=0; i<m_size; i++)
for (int j=0; j<n_size; j++) {
counter++;
if (counter % range == 0) {
int val1 = 0;
for (k = 0; k < k_size; k++) {
Program.result[i][j] += Program.m1[i][k] * Program.m2[k][j];
// int val1 =0;
for (int h=0; h<h_size; h++){
val1 += Program.result[i][h] * Program.m3[h][j];
}
}
Program.result_matrix[i][j] = val1; //here run error
}
}
}
public class Program {
private final static Random rand = new Random();
public static int[][] m1 = new int[][]{};
public static int[][] m2 = new int[][]{};
public static int[][] m3 = new int[][]{};
public static int[][] result = new int[][]{};
public static int[][] result_matrix = new int[][]{};
public static void generate(String action, int number_of_threads) throws InterruptedException {
List<Thread> all_threads = new ArrayList<>();
for (int th = 0; th < number_of_threads; th++) {
Thread t = new Thread(new Threads(action, th));
all_threads.add(t);
t.start();
}
for (Thread t : all_threads) {
t.join();
}
}
public static void main(String[] args) throws Exception {
{ //here i m reading the matrices
generate(action, number_of_threads);
print_result_matrix();
public static void print_result_matrix() {
for (int i = 0; i < result_matrix.length; i++) {
for (int j = 0; j < result_matrix[0].length; j++)
System.out.print(result_matrix[i][j] + " ");
System.out.println();
}
}
When I run this program I got an error after setting the matrices rows and columns and gives me error at line //look at code.
Anyway some ideas?I know that my code doesn't have a logic in run() method at the end but I really don't know how to achieve this.
Any ideas?
Stacktrace:
Exception in thread "Thread-0" Exception in thread "Thread-1 java.lang.ArrayIndexOutOfBoundsException: 0
at Threads.run(Threads.java:43)
at java.lang.Thread.run(Thread.java:745) java.lang.ArrayIndexOutOfBoundsException: 0
at Threads.run(Threads.java:43)
at java.lang.Thread.run(Thread.java:745)
You need to initialize result matrices' sizes:
public static int[][] result = new int[m1.length][m2[0].length];
public static int[][] result_matrix = new int[result.length][m3[0].length];
Of course, this should be done after m1, m2 and m3 are filled with data.
I've been writing the following code for my OS course and I got some weird results. The code creates x threads and runs them concurrently in order to multiply two squared matrices. Every thread will multiply Number_of_rows/Number_of_threads rows of the input matrices.
When running it on a 1024X1024 matrices, with 1...8 threads, I get that the fastest multiplication happens when using only one thread. I would expect that a MacBook pro with i5 processor (2-cores) will utilize the two cores and that will yield faster results when using two threads.
Running time goes from about ~9.2 seconds using one thread, ~9.6 seconds to 27 seconds using 8.
Any idea why this is happening?
BTW, A few things about the code:
a. Assume that both matrices have identical dimensions and are square.
b. Assume that number of threads <= number of rows/columns.
public class MatrixMultThread implements Runnable {
final static int MATRIX_SIZE = 1024;
final static int MAX_THREADS = MATRIX_SIZE;
private float[][] a;
private float[][] b;
private float[][] res;
private int startIndex;
private int endIndex;
public MatrixMultThread(float[][] a, float[][]b, float[][] res, int startIndex, int endIndex) {
this.a = a;
this.b = b;
this.res = res;
this.startIndex = startIndex;
this.endIndex = endIndex;
}
public void run() {
float value = 0;
for (int k = startIndex; k < endIndex; k++) {
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
value += a[k][j]*b[j][i];
}
res[k][i] = value;
value = 0;
}
}
}
public static float[][] mult(float[][] a, float[][] b, int threadCount){
// Get number of rows per each thread.
int rowsPerThread = (int) Math.ceil(MATRIX_SIZE / threadCount);
float[][] res = new float[MATRIX_SIZE][MATRIX_SIZE];
// Create thread array
Thread[] threadsArray = new Thread[threadCount];
int rowCounter = 0;
for (int i = 0; i < threadCount; i++) {
threadsArray[i] = new Thread(new MatrixMultThread(a,b,res,rowCounter, Math.max(rowCounter + rowsPerThread, MATRIX_SIZE)));
threadsArray[i].start();
rowCounter += rowsPerThread;
}
// Wait for all threads to end before finishing execution.
for (int i = 0; i < threadCount; i++) {
try {
threadsArray[i].join();
} catch (InterruptedException e) {
System.out.println("join failed");
}
}
return res;
}
public static void main(String args[]) {
// Create matrices and random generator
Random randomGenerator = new Random();
float[][] a = new float[MATRIX_SIZE][MATRIX_SIZE];
float[][] b = new float[MATRIX_SIZE][MATRIX_SIZE];
// Initialize two matrices with initial values from 1 to 10.
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
a[i][j] = randomGenerator.nextFloat() * randomGenerator.nextInt(100);
b[i][j] = randomGenerator.nextFloat() * randomGenerator.nextInt(100);
}
}
long startTime;
for (int i = 1; i <= 8; i++) {
startTime = System.currentTimeMillis();
mult(a,b,i);
System.out.println("Total running time is: " + (System.currentTimeMillis() - startTime) + " ms");
}
}
}
Firstly a bit of logging helps. I did logging for this and found out a bug in your logic.
Here is the log
Starting execution for thread count: 1
Start index: 0
End index: 1024
Starting execution: MatrixMultiplier: 0
Ending executionMatrixMultiplier: 0
Total running time is: 6593 ms
Starting execution for thread count: 2
Start index: 0
End index: 1024 <------ This is the problem area
Start index: 512
End index: 1024
Starting execution: MatrixMultiplier: 1
Starting execution: MatrixMultiplier: 0
Your first thread in all iterations is performing whole multiplication everytime. That's why you are not seeing results. Figure out the bug.
I would like to simulate a situation which is mentioned in books about concurrency - that without a proper synchronization one thread can see a stale value of a variable that has been already modified by a different thread. This could happen because for example a CPU cache.
To do this I have written the following program. The idea is that there are 4 threads that initialize a different part of a shared array. The 5th thread (main, parent thread) waits until all 4 previous threads are done, iterates over the shared array and adds its values (always 1 or if I'm lucky null, which would mean a stale value)
package p1;
class ArrFill implements Runnable {
int l, r;
Integer[] arr;
ArrFill(int l, int r, Integer[] arr) {
this.l = l;
this.r = r;
this.arr = arr;
}
#Override
public void run() {
for(int i = l; i < r; i++)
arr[i] = new Integer(1);
}
}
public class Main {
final static int MAX = 10000000;
final static int tnum = 4;
public static void main(String[] args) throws InterruptedException {
int cores = Runtime.getRuntime().availableProcessors();
System.out.println(cores);
Integer[] arr = new Integer[MAX];
Thread[] t = new Thread[tnum];
if(MAX % tnum != 0)
throw new IllegalStateException();
int step = MAX / tnum;
int l = 0, r = 0;
for(int i = 0; i < tnum; i++) {
l = r;
r += step;
t[i] = new Thread(new ArrFill(l, r, arr));
t[i].start();
}
for(int i = 0; i < tnum; i++)
t[i].join();
int res = 0;
for(int i = 0; i < MAX; i++)
if(arr[i] != null)
res += arr[i];
System.out.println(res == MAX);
}
}
I have run this program many times although I never seen a stale value (null). I have 2 cores. Do you have any idea how this program could be improved to actually present the cached value phenomena? Or maybe you have a completly different approach?
Thanks!
I am trying to do a modelling for some algorithms in java, what i am facing now is i need to run the main of the algorithm 10 times but the process takes 120 minutes to finish so i am doing each run on a thread. What i want is to create 10 threads without repeating the same code in each thread so how to make 10 different threads with the same code to excute. any ideas.
package biodavidcorne;
import java.util.Random;
/**
*
* #author hyder
*/
public class BIODavidCorne extends Thread {
public void run(int Runs) {
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
BIODavidCorne test = new BIODavidCorne();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
try {
int Runs = 0;
int[][] Mean10Runs = new int[10][10000];
int[][] Min10Runs = new int[10][10000];
int[][] Max10Runs = new int[10][10000];
// for (int Runs = 0; Runs < 10; Runs++) {
BinList test = new BinList();
Random generator = new Random();
for (int i = 0; i < 10; i++) {
test.ReadLine("File.txt", i);
}
//test.PrintListOfGarbage();
for (int i = 0; i < 10; i++) {
test.InsertGarbageToBin(i);
}
for (int Big = 0; Big < 10000; Big++) {
int Mean = 0;
for (int x = 0; x < 10; x++) {
for (int i = 0; i < 50; i++) {
test.GetPenalties(x, i);
}
}
// System.out.println("*******************************************************************************************" + Big + " .. " + Runs);
// test.PrintListOfGarbage();
int[] penalty = new int[10];
int[] minimum = new int[10];
int[] maximum = new int[10];
int[] mutation = new int[10];
// test.PrintListOfGarbage();
for (int i = 0; i < 10; i++) {
penalty[i] = test.getAllPanalties(i);
}
for (int i = 0; i < 10; i++) {
minimum[i] = test.getMinimum(i);
maximum[i] = test.getMaximum(i);
mutation[i] = test.calculateMutation(penalty[i], minimum[i], maximum[i]);
//
}
int r = generator.nextInt(10);
int s = generator.nextInt(10);
test.MakeTheFitness(mutation, r, s);
test.resetPenaltyArray();
// test.PrintListOfGarbage();
for (int i = 0; i < 10; i++) {
Mean = Mean + mutation[i];
}
int min = mutation[0];
int max = 0;
for (int i = 0; i < 10; i++) {
if (min > mutation[i]) {
min = mutation[i];
}
if (max < mutation[i]) {
max = mutation[i];
}
}
Min10Runs[Runs][Big] = min;
Max10Runs[Runs][Big] = max;
Mean10Runs[Runs][Big] = (Mean / 10);
System.out.println("This is the Mean 1"+Big+".."+Runs);
}
System.out.println("This is the Mean + for Runs" + Runs + ".. " + Mean10Runs[Runs][9999] + "This is the Minimum " + Min10Runs[Runs][9999]);
} catch (Exception e) {
System.out.println("Not supported yet." + e);
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
try {
int Runs = 0;
int[][] Mean10Runs = new int[10][10000];
int[][] Min10Runs = new int[10][10000];
int[][] Max10Runs = new int[10][10000];
// for (int Runs = 0; Runs < 10; Runs++) {
BinList test = new BinList();
Random generator = new Random();
for (int i = 0; i < 10; i++) {
test.ReadLine("File.txt", i);
}
//test.PrintListOfGarbage();
for (int i = 0; i < 10; i++) {
test.InsertGarbageToBin(i);
}
for (int Big = 0; Big < 10000; Big++) {
int Mean = 0;
for (int x = 0; x < 10; x++) {
for (int i = 0; i < 50; i++) {
test.GetPenalties(x, i);
}
}
// System.out.println("*******************************************************************************************" + Big + " .. " + Runs);
// test.PrintListOfGarbage();
int[] penalty = new int[10];
int[] minimum = new int[10];
int[] maximum = new int[10];
int[] mutation = new int[10];
// test.PrintListOfGarbage();
for (int i = 0; i < 10; i++) {
penalty[i] = test.getAllPanalties(i);
}
for (int i = 0; i < 10; i++) {
minimum[i] = test.getMinimum(i);
maximum[i] = test.getMaximum(i);
mutation[i] = test.calculateMutation(penalty[i], minimum[i], maximum[i]);
//
}
int r = generator.nextInt(10);
int s = generator.nextInt(10);
test.MakeTheFitness(mutation, r, s);
test.resetPenaltyArray();
// test.PrintListOfGarbage();
for (int i = 0; i < 10; i++) {
Mean = Mean + mutation[i];
}
int min = mutation[0];
int max = 0;
for (int i = 0; i < 10; i++) {
if (min > mutation[i]) {
min = mutation[i];
}
if (max < mutation[i]) {
max = mutation[i];
}
}
Min10Runs[Runs][Big] = min;
Max10Runs[Runs][Big] = max;
Mean10Runs[Runs][Big] = (Mean / 10);
System.out.println("This is the Mean 2"+Big+".."+Runs);
}
} catch (Exception e) {
System.out.println("Not supported yet." + e);
}
}
});
t1.start();
t2.start();
}
}
Just make the Runnable a named class instead of an anonymous inner class, and reuse it:
class MyRunnable implements Runnable {
#Override
public void run() {
int Runs = 0;
int[][] Mean10Runs = new int[10][10000];
// ...
new Thread(new MyRunnable()).start();
You can (and should) put MyRunnable in its own source file.
There is no reason to copy and paste the content of the anonymous inner class ten times. Just assign it to a variable and use it 10 times.
Runnable runnable = new Runnable() {
#Override
public void run() {
// ... the code in the anonymous inner class
}
}
// Start 10 threads with this code
for (int i = 0; i < 10; ++i) {
new Thread(runnable).start();
}
You can use a for loop to create the threads.
Also, if you want to ensure that all of the threads kick off at the same time, you can use a CyclicBarrier, but if not you can just start each thread as you create it.
If you need to hold a reference to the threads, store them in a Thread array
CyclicBarrier barrier = new CyclicBarrrier(10);
// Runnable runnable = ... your code. at the beginning of the Runnable put the first line
barrier.await(); // and catch the exception
Thread[] threads = new Thread[10];
for(int i = 0; i < 10; i++){
threads[i] = new Thread(runnable);
threads[i].start();
}
That's it! Good luck - let me know if you need help implementing the runnable
Unless you have 10 CPU cores do not spawn 10 threads.
You can use commons threadpool and set it the size of the number of cpu cores, so you can run the tasks in parallel and sequentially.
try using a ThreadPoolExecutor
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html
Create a class that extends Thread and implement the run method. You could pass argument through the constructor, keep them as members to use them in the run() method.
Something like this:
public class YourThread extends Thread{
private String mParam1;
private Object mParam2;
public YourThread( String param1, Object param2 ){
mParam1 = param1;
mParam2 = param2;
}
public void run(){
// do your stuff here
// ...
}
}
In the other class:
YourThread t1 = new Thread( "toto", new Object() );
t1.start();
YourThread t2 = new Thread( "titi", new Object() );
t2.start();
I want to make a simple math operations on a vector(array) using two cores of my CPU. The program doesn't work correctly. Please explain me how to solve my problem.
public class MyRunnable implements Runnable {
private int startIndex;
private int endIndex;
private float[] tab;
public MyRunnable(int startIndex, int endIndex, float[] tab)
{
this.startIndex = startIndex;
this.endIndex = endIndex;
this.tab = tab;
}
#Override
public void run()
{
System.out.println(Thread.currentThread());
for(int i = startIndex; i < endIndex; i++)
{
tab[i] = i * 2;
}
System.out.println("Finished");
}
}
public class Test {
public static void main(String[] args) {
int size = 10;
int n_threads = 2;
float tab[] = new float[size];
for(int i = 0; i < size; i++)
{
tab[i] = i;
}
System.out.println(Thread.currentThread());
for(int i = 0; i < size; i++)
{
System.out.println(tab[i]);
}
Runnable r1 = new MyRunnable(0, size / n_threads, tab );
Runnable r2 = new MyRunnable(size / n_threads, size, tab );
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
for(int i = 0; i < size; i++)
{
System.out.println(tab[i]);
}
}
It seems like you don't wait for the threads to finish. Use the join method and add
t1.join();
t2.join();
just before the output loop.
As pointed out by others, you are not waiting for your threads to finish execution. You should follow the advice of #Howard and #JK and that will fix your basic issue. If you decide to do more with threads and parallel processing though I would highly advice looking into the java.util.concurrent packages - they have many useful classes that will make your life much easier.
I took the liberty of recoding your example using Callable and ExecutorService. Please see the sample code below:
public static void main(String[] args) {
int size = 10;
int n_threads = 2;
float tab[] = new float[size];
for (int i = 0; i < size; i++) {
tab[i] = i;
}
System.out.println(Thread.currentThread());
for (int i = 0; i < size; i++) {
System.out.println(tab[i]);
}
// Determine batch size, based off of number of available
// threads.
int batchSize = (int) Math.ceil((double) size / n_threads);
System.out.println("Size: " + size + " Num threads: " + n_threads
+ " Batch Size: " + batchSize);
// Create list of tasks to run
List<Callable<Object>> tasks = new ArrayList<Callable<Object>>(
n_threads);
for (int i = 0; i < n_threads; i++) {
tasks.add(Executors.callable(new MyRunnable(i * batchSize,
((i + 1) * batchSize) - 1, tab)));
}
// Create an executor service to handle processing tasks
ExecutorService execService = Executors.newFixedThreadPool(n_threads);
try {
execService.invokeAll(tasks);
} catch (InterruptedException ie) {
ie.printStackTrace();
} finally {
execService.shutdown();
}
for (int i = 0; i < size; i++) {
System.out.println(tab[i]);
}
}
And made one slight change in your MyRunnable class, which was skipping processing on the last index:
#Override
public void run() {
System.out.println(Thread.currentThread());
for (int i = startIndex; i <= endIndex; i++) {
tab[i] = i * 2;
}
System.out.println("Finished");
}
Works great, you can test for yourself. Theres many more classes in java.util.concurrent that can do similar functionality, feel free to explore.
Good luck!
You can wait for the threads to finish execution by inserting calls to Thread.join():
t1.join();
t2.join();
after your x.start() function call to pause until the threads have completed. Otherwise you cannnot know if they are finished executing or not.
You should also consider synchronizing your tab[] accesses within the separate threads with a mutex/semaphore or similar mechanism, and not necessarily perform calculations directly on the passed in array reference, since this can limit the amount of concurrency (if present).