Java. Умножение матриц произвольных размеров с помощью фиксированного числа поток
я новичок в многопоточных вычислениях; Мне нужно умножить две матрицы с использованием потоков. Я хочу использовать ленточный алгоритм с использованием горизонтальных полос (т.е. строки первой исходной матрицы умножаем на столбцы второй исходной (т.е. на строки её транспонированной). Главные вопросы: как мне оформить циклический обмен строками транспонированной матрицы? И как мне из потоков вернуть tempRes для записи в Res. Заранее спасибо за помощь. Вот мой код:
Класс Main:
import static java.lang.Math.round;
public class Main {
public static void main(String[] args) throws InterruptedException {
final int n = 1;
final int m = 2;
final int k = 3;
double[] arr_1 = new double[n * m];
double[] arr_2 = new double[m * k];
double[] res = new double[n * k];
for (int i = 0; i < n * m; i++) {
arr_1[i] = round(Math.random() * 50 + 100);
}
for (int i = 0; i < m * k; i++) {
arr_2[i] = round(Math.random() * 40 + 20);
}
System.out.println("Show Matrix_1: ");
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
System.out.print(arr_1[i * m + j] + " ");
}
System.out.println();
}
System.out.println();
System.out.println("Show Matrix_2: ");
for (int i = 0; i < m; i++) {
for (int j = 0; j < k; j++) {
System.out.print(arr_2[i * k + j] + " ");
}
System.out.println();
}
System.out.println();
double[] new_arr_2 = new double[k * m];
for (int i = 0; i < m; i++) {
for (int j = 0; j < k; j++) {
new_arr_2[j * m + i] = arr_2[i * k + j];
}
}
System.out.println("Show New_Matrix_2: ");
for (int i = 0; i < k; i++) {
for (int j = 0; j < m; j++) {
System.out.print(new_arr_2[i * m + j] + " ");
}
System.out.println();
}
System.out.println();
/* тут я равномерно распределяю строки массивов, т.к не факт, что они будут кратны количеству потоков */
int kolvo_nerasprstrok_arr_1 = n;
int kolvo_nerasprstrok_new_arr_2 = k;
int kolvoThread = 3;
Thread[] threads = new Thread[kolvoThread];
int []kolvoStrokThr_arr_1 = new int [kolvoThread];
int []kolvoStrokThr_new_arr_2 = new int [kolvoThread];
double timeStart = System.currentTimeMillis();
for (int i = kolvoThread - 1; i >= 0; i--) {
kolvoStrokThr_arr_1[i] = kolvo_nerasprstrok_arr_1 / (i + 1);
kolvoStrokThr_new_arr_2[i] = kolvo_nerasprstrok_new_arr_2 / (i + 1);
kolvo_nerasprstrok_arr_1 -= kolvoStrokThr_arr_1[i];
kolvo_nerasprstrok_new_arr_2 -= kolvoStrokThr_new_arr_2[i];
}
/* т.к. мы циклично пересылаем строки транспонированной матрицы, то нужно установить фиксированную одинаковую размерность для потоков. Иначе, допустим, я не знаю, как реализовать цикличный обмен, например, двух и трёх строк */
int max_strok_Thr_new_arr_2 = 0;
for (int i = kolvoThread - 1; i >= 0; i--)
{
if (kolvoStrokThr_new_arr_2[i] > max_strok_Thr_new_arr_2)
{
max_strok_Thr_new_arr_2 = kolvoStrokThr_new_arr_2[i];
}
}
/*делаю массивы с элементами для потоков, передаю их и запускаю сами потоки */
int kolvo_raspred_elems_arr_1 = 0;
int kolvo_raspred_elems_new_arr_2 = 0;
for (int i = kolvoThread - 1; i >= 0; i--) {
double[] elems_1 = new double[kolvoStrokThr_arr_1[i] * m];
double[] elems_2 = new double[max_strok_Thr_new_arr_2 * m];
double[] tempRes = new double[kolvoStrokThr_arr_1[i] * max_strok_Thr_new_arr_2];
int t = 0;
for (int j = kolvo_raspred_elems_arr_1; j < kolvo_raspred_elems_arr_1 + kolvoStrokThr_arr_1[i] * m ; j++) {
elems_1[t] = arr_1[j];
t++;
}
t = 0;
for (int j = kolvo_raspred_elems_new_arr_2; j < kolvo_raspred_elems_new_arr_2 + kolvoStrokThr_new_arr_2[i] * m; j++) {
elems_2[t] = new_arr_2[j];
t++;
}
System.out.println();
kolvo_raspred_elems_arr_1 += kolvoStrokThr_arr_1[i] * m;
kolvo_raspred_elems_new_arr_2 += kolvoStrokThr_new_arr_2[i] * m;
threads[i] = new Thread(new Mult(kolvoStrokThr_arr_1[i], max_strok_Thr_new_arr_2, elems_1, elems_2, tempRes, m), "Thread-" + i);
threads[i].start();
}
(*тут ещё немного кода дописать *)
Класс Mult:
public class Mult extends Thread{
private final int m, kolvoStrokThr_arr_1,max_strok_Thr_new_arr_2;
private final double []elems_1, elems_2, tempRes;
public Mult(int kolvoStrokThr_arr_1, int max_strok_Thr_new_arr_2 ,double[]elems_1, double[] elems_2, double[]tempRes, int m)
{
this.kolvoStrokThr_arr_1 = kolvoStrokThr_arr_1;
this.max_strok_Thr_new_arr_2 = max_strok_Thr_new_arr_2;
this.elems_1 = elems_1;
this.elems_2 = elems_2;
this.tempRes = tempRes;
this.m = m;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
for (int i = 0; i < kolvoStrokThr_arr_1; i++) {
for (int j = 0; j < max_strok_Thr_new_arr_2; j++) {
for (int k = 0; k < m; k++) {
tempRes[i * m + j] += elems_1[i * m + k] * elems_2[j * m + k];
System.out.println(elems_1[i * m + k]);
System.out.println(elems_2[j * m + k]);
System.out.println(tempRes[i * m + j]);
}
}
}
System.out.println();
}