Как правильно умножить матрицу на другую матрицу в нескольких потоках? Моя задача такая. Мне нужно параллельно на 8 потоках умножить матрицу 200x248 на матрицу 248x333. В интернете я нашел простой пример умножения двух матриц 4x4 на 4 потоках, но я не совсем понимаю логику разделения этой задачи между потоками. Почему у каждого потока разные границы циклов и как они вообще образовываются? Почему в каждом потоке аж 3 цикла, а не 2? Можете мне объяснить алгоритм, чтобы я мог по его аналогии сделать умножение огромных матриц на 8 потоках?
Вот часть этого кода (там еще есть ввод данных с файла и вывод результата в другой файл, графический интерфейс и другое, но это не столь важно в этом вопросе).
Инициализация статических полей:public static int[][] a;
public static int[][] b;
public static int[][] c;
Где-то в main создаются и запускаются потоки:c = new int[a.length][b[0].length];
Thread1 thread1 = new Thread1();
Thread2 thread2 = new Thread2();
Thread3 thread3 = new Thread3();
Thread4 thread4 = new Thread4();
thread1.start();
thread2.start();
thread3.start();
thread4.start();
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
thread3.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
thread4.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Код четырех потоков:public static class Thread1 extends Thread {
@Override
public void run() {
int m = a.length;
int n = b[0].length;
int k = (a.length) / 4;
for (int i = 0; i <= k; i++) {
for (int j = 0; j < n; j++) {
for (int l = 0; l < b.length; l++) {
c[i][j] = c[i][j] + a[i][l] * b[l][j];
}
}
}
}
}
public static class Thread2 extends Thread {
@Override
public void run() {
int m = a.length;
int n = b[0].length;
int k = (a.length) / 2 + 1;
int s = ((a.length) / 4) + 1;
for (int i = s; i < k; i++) {
for (int j = 0; j < n; j++) {
for (int l = 0; l < b.length; l++) {
c[i][j] = c[i][j] + a[i][l] * b[l][j];
}
}
}
}
}
public static class Thread3 extends Thread {
@Override
public void run() {
int m = a.length;
int n = b[0].length;
int k = ((3 * (a.length)) / 4) + 1;
int s = (a.length) / 2 + 1;
for (int i = s; i < k; i++) {
for (int j = 0; j < n; j++) {
for (int l = 0; l < b.length; l++) {
c[i][j] = c[i][j] + a[i][l] * b[l][j];
}
}
}
}
}
public static class Thread4 extends Thread {
@Override
public void run() {
int m = a.length;
int n = b[0].length;
int k = ((3 * (a.length)) / 4) + 1;
for (int i = k; i < m; i++) {
for (int j = 0; j < n; j++) {
for (int l = 0; l < b.length; l++) {
c[i][j] = c[i][j] + a[i][l] * b[l][j];
}
}
}
}
}

21 Авг 2019 в 06:11
184 +1
0
Ответы
1

Алгоритм разделения задачи умножения матриц на несколько потоков следующий:

Делим результат на число потоков. В вашем случае вы хотите использовать 8 потоков, поэтому делим количество строк матрицы A на 8, чтобы получить границы обработки для каждого потока.

Создаем класс потока, где каждый поток будет обрабатывать свой участок результатной матрицы. В вашем случае это заполнение столбцов результирующей матрицы.

В цикле каждый поток пробегается по своей части результатной матрицы, умножая соответствующие элементы соответствующих строк матриц A и B и записывая результат в соответствующий элемент матрицы C.

После завершения всех потоков, собираем результаты в общей результирующей матрице.

Осуществляем синхронизацию потоков, чтобы дождаться их завершения перед объединением результатов в общую матрицу.

Что касается вашего кода, границы циклов в каждом потоке правильно определены для разделения обработки между потоками. Количество циклов зависит от того, как вы разбили обработку. В вашем случае, чтобы умножить матрицу 200x248 на матрицу 248x333 на 8 потоках, вам нужно дополнительно разделить один из измерений на 8, чтобы обеспечить параллелизм.

20 Апр в 13:22
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Название заказа не должно быть пустым
Введите email
Бесплатные доработки
Гарантированные бесплатные доработки
Быстрое выполнение
Быстрое выполнение от 2 часов
Проверка работы
Проверка работы на плагиат
Интересные статьи из справочника
Поможем написать учебную работу
Название заказа не должно быть пустым
Введите email
Доверьте свою работу экспертам
Разместите заказ
Наша система отправит ваш заказ на оценку 92 648 авторам
Первые отклики появятся уже в течение 10 минут
Прямой эфир