Использование ThreadPool для распараллеливания умножения матриц

1

Я пытаюсь параллельно умножить матрицу.

Я достиг распараллеливания, вычисляя каждую ячейку матрицы C в отдельном потоке. (Надеюсь, я сделал это правильно).

Мой вопрос здесь в том, что использование пула потоков - лучший способ для создания потоков. (Извините, я не знаком с этим, и кто-то предложил сделать так)

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

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ParallelMatrix {

public final static int N = 2000; //Random size of matrix
public static void main(String[] args) throws InterruptedException {

    long startTime = System.currentTimeMillis();

    //Create and multiply matrix of random size N.   
    double [][] a = new double [N][N];
    double [][] b = new double [N][N];
    double [][] c = new double [N][N];

    int i,j,k;

    for(i = 0; i < N ; i++) {
        for(j = 0; j < N ; j++){
            a[i][j] = i + j;
            b[i][j] = i * j;
        }

        ExecutorService pool = Executors.newFixedThreadPool(1);
        for(i = 0; i < N; i++) {
            for(j = 0; j < N; j++) {  
                pool.submit(new Multi(N,i,j,a,b,c));
            }
        }
        pool.shutdown();
        pool.awaitTermination(1, TimeUnit.DAYS);
        long endTime = System.currentTimeMillis();
        System.out.println("Calculation completed in " +
             (endTime - startTime) + " milliseconds");

    }
    static class Multi implements Runnable {
        final int N;
        final double [][] a;
        final double [][] b;
        final double [][] c;
        final int i;
        final int j;

        public Multi(int N, int i, int j, double[][] a, double[][] b, double[][] c){
            this.N=N;
            this.i=i;
            this.j=j;
            this.a=a;
            this.b=b;
            this.c=c;
        }

        @Override
        public void run() {
            for(int k = 0; k < N; k++) 
                c[i][j] += a[i][k] * b[k][j];
        }
    }
}
  • 0
    Я пишу многопоточный код в java уже более десяти лет и никогда не использовал ни одного из классов в java.util.concurrent.Executors. Это что-то значит, но я понятия не имею, что это такое.
  • 0
    Да, я знаю, но это был способ, которым кто-то предложил закодировать это здесь. Если у вас есть альтернативный способ сделать то же самое, пожалуйста, поделитесь.
Теги:
multithreading
matrix
threadpool

1 ответ

2
Лучший ответ

Вы должны балансировать между накладными расходами на планирование, продолжительностью работы и количеством доступных ядер. Для начала размер пула потоков в соответствии с количеством ядер, доступных newFixedThreadPool(Runtime.getRuntime().availableProcessors()).

Чтобы свести к минимуму расходы на планирование, вы хотите разрезать операцию на столько независимых задач (в идеале равное время выполнения), как у вас есть процессоры.

Как правило, чем меньше операция, которую вы выполняете в срезе, тем больше у вас накладных расходов. То, что у вас есть (N квадратных задач), имеет чрезмерные накладные расходы (вы создадите и отправьте 2000 раз 2000 Multi runnables, каждый из которых мало работает).

  • 0
    Хорошо, я понял! Спасибо! Таким образом, я достиг паралелизма тогда :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню