简体   繁体   English

使用线程池的Java矩阵乘法

[英]Java Matrix Multiplication using Thread Pool

I'm trying to implement a program that can do matrix multiplication using Callable (thread pool). 我正在尝试使用Callable(线程池)实现可以进行矩阵乘法的程序。 I have this program below. 我有这个程序如下。 But, I don't see any significant difference in execution time when I run this on one thread or 8 threads. 但是,当我在一个线程或8个线程上运行时,我没有看到执行时间有任何显着差异。

I took 5 samples for one thread and 8 thread, they're as follows (all in milliseconds): 我为一个线程和8个线程取了5个样本,它们如下(全部以毫秒为单位):

1 thread - 5433.982472 , 6872.947063 , 6371.205237 , 6079.367443 , 5842.946494 1个主题 - 5433.982472,6872.947063,6371.205237,6079.367443,5842.946494

8 threads - 5260.792683 , 5517.047691 , 5314.208147 , 5739.747367 , 5585.621661 8个主题 - 5260.792683,5517.047691,5314.208147,5739.747367,5585.621661

I'm new to this, am I doing anything wrong? 我是新手,我做错了什么?

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);



    }
}

Running a program in multiple threads doesn't necessarily means better performance. 在多个线程中运行程序并不一定意味着更好的性能。 In few cases it can result in worse performance. 在少数情况下,它可能导致更差的性能。 You have to check what all other processes running on your system? 您必须检查系统上运行的所有其他进程? How many CPU cores you have? 你有多少CPU核心?

If you have dual core processor and you run 8 threads means more work for java to coordinates between threads. 如果你有双核心处理器,你运行8个线程意味着更多的工作java来线程之间的坐标。 For best performance try running the same number of threads as number of CPU cores with minimum services running on your PC/server. 为了获得最佳性能,请尝试运行与CPU核心数相同的线程数,并在PC /服务器上运行最少的服务。

By calling future.get() right after executor.submit(...) , you are preventing any actual multithreading. 通过在executor.submit(...)之后调用future.get() ,您可以防止任何实际的多线程。 Your program waits for the first computation to complete before it submits the second one. 您的程序在提交第二个计算之前等待第一个计算完成。

To illustrate this, try replacing your loop with the following: 为了说明这一点,请尝试使用以下代码替换您的循环:

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

This is not exactly a great way to do it, but you should see a significant improvement in your execution time. 这不是一个很好的方法,但你应该看到你的执行时间显着改善。 The difference is that now you are starting up all the computations in all your threads and then start collecting the results. 不同之处在于,现在您在所有线程中启动所有计算,然后开始收集结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM