2015-03-24 3 views
1

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

Я достиг распараллеливания, вычислив каждую ячейку матрицы 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

Да, я знаю, но это было так, как кто-то предложил закодировать это здесь. Если у вас есть альтернативный способ сделать то же самое, пожалуйста, поделитесь. –

ответ

2

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

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

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

+0

Хорошо, я понимаю! Благодаря! Так что я достиг парралинизма тогда :) –

Смежные вопросы