【问题标题】:Java Matrix Multiplication using Thread Pool使用线程池的 Java 矩阵乘法
【发布时间】:2017-03-18 02:40:08
【问题描述】:

我正在尝试实现一个可以使用 Callable(线程池)进行矩阵乘法的程序。我在下面有这个程序。但是,当我在一个线程或 8 个线程上运行它时,我看不到执行时间有任何显着差异。

我为一个线程和 8 个线程取了 5 个样本,它们如下(均以毫秒为单位):

1 个线程 - 5433.982472、6872.947063、6371.205237、6079.367443、5842.946494

8 线程 - 5260.792683、5517.047691、5314.208147、5739.747367、5585.621661

我是新手,我做错了什么吗?

package naivematmul;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.Callable;

 class NaiveMatMul implements Callable<Integer>
{
    private int n;
    private int a[][];
    private int b[][];
    private int sum;
    private int i;
    private int j;


    public NaiveMatMul(int n, int a[][], int b[][], int i , int j )
    {
            this.n = n;
            this.a = a;
            this.b = b;
            this.i = i;
            this.j = j;
            this.sum = sum;
    }

    public Integer call() throws Exception
    {
        for (int k = 0 ; k < n ; k++)
         {
             sum = sum + a[i][k] * b[k][j];

         }
         return sum;
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException 
    {

        int n;
        int[][] a, b, c;

        n = 512;
        a = new int[n][n];
        b = new int[n][n];
        c = new int[n][n];

         int threads = 8;

        ExecutorService executor = Executors.newFixedThreadPool(threads);

        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                a[i][j] = 1;
            }
        }

        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {

                b[i][j] = 1;

            }
        }


          int sum = 0;
         long start_time = System.nanoTime();
      Future<Integer> future;

        for (int i = 0; i < n ; i++)
        {
            for (int j = 0 ; j < n ; j++)
            {
                future = executor.submit(new NaiveMatMul(n, a, b, i, j));
                c[i][j] = future.get();
                sum = 0;
            }

        }


        long end_time = System.nanoTime();
        double difference = (end_time - start_time)/1e6;
        executor.shutdown();




                System.out.println("Time taken : " + difference);



    }
}

【问题讨论】:

    标签: java multithreading matrix-multiplication


    【解决方案1】:

    通过在executor.submit(...) 之后调用future.get(),您可以阻止任何实际的多线程。您的程序在提交第二个计算之前等待第一个计算完成。

    为了说明这一点,请尝试将循环替换为以下内容:

    Future<Integer> futures[][] = new Future[n][n];
    
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            future = executor.submit(new NaiveMatMul(n, a, b, i, j));
            futures[i][j] = future;
        }
    }
    
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            c[i][j] = futures[i][j].get();
        }
    }
    

    这并不是一个很好的方法,但您应该会看到执行时间的显着改善。不同之处在于,现在您正在启动所有线程中的所有计算,然后开始收集结果。

    【讨论】:

    • 3个线程后执行时间增加。知道为什么会这样吗?我在带有超线程的四核 i7 上运行它,所以它总共有 8 个线程。另外,我使用的 IDE 是 NetBeans。
    • 我参加聚会有点晚了,但是如果你增加矩阵的大小,情况会更好吗?就这些东西而言,512 并没有那么大
    • Future&lt;Integer&gt; futures[][] = new Future[n][n]; 给我错误:generic array creation Future&lt;Integer&gt; futures[][] = new Future&lt;Integer&gt; [rowsA][colsB];
    【解决方案2】:

    在多个线程中运行程序并不一定意味着更好的性能。在少数情况下,它可能会导致性能下降。您必须检查系统上运行的所有其他进程?你有多少个 CPU 内核?

    如果你有双核处理器并且你运行 8 个线程,这意味着 java 需要更多的工作来协调线程之间的工作。 为获得最佳性能,请尝试运行与 CPU 内核数相同的线程数,同时在您的 PC/服务器上运行最少的服务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-16
      • 2015-01-23
      相关资源
      最近更新 更多