簡體   English   中英

使用線程池的Java矩陣乘法

[英]Java Matrix Multiplication using Thread Pool

我正在嘗試使用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);



    }
}

在多個線程中運行程序並不一定意味着更好的性能。 在少數情況下,它可能導致更差的性能。 您必須檢查系統上運行的所有其他進程? 你有多少CPU核心?

如果你有雙核心處理器,你運行8個線程意味着更多的工作java來線程之間的坐標。 為了獲得最佳性能,請嘗試運行與CPU核心數相同的線程數,並在PC /服務器上運行最少的服務。

通過在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();
    }
}

這不是一個很好的方法,但你應該看到你的執行時間顯着改善。 不同之處在於,現在您在所有線程中啟動所有計算,然后開始收集結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM