Java 多线程矩阵乘法性能问题

Java 多线程矩阵乘法性能问题,java,multithreading,Java,Multithreading,我正在使用java进行多线程乘法。我正在练习多线程编程。下面是我从stackoverflow的另一篇文章中获取的代码 public class MatMulConcur { private final static int NUM_OF_THREAD =1 ; private static Mat matC; public static Mat matmul(Mat matA, Mat matB) { matC = new Mat(matA.getNRows(),matB.getNColum

我正在使用java进行多线程乘法。我正在练习多线程编程。下面是我从stackoverflow的另一篇文章中获取的代码

public class MatMulConcur {

private final static int NUM_OF_THREAD =1 ;
private static Mat matC;

public static Mat matmul(Mat matA, Mat matB) {
matC = new Mat(matA.getNRows(),matB.getNColumns());
return mul(matA,matB);
}

private static Mat mul(Mat matA,Mat matB) {

int numRowForThread;
int numRowA = matA.getNRows();
int startRow = 0;

Worker[] myWorker = new Worker[NUM_OF_THREAD];

for (int j = 0; j < NUM_OF_THREAD; j++) {
    if (j<NUM_OF_THREAD-1){
        numRowForThread = (numRowA / NUM_OF_THREAD);
    } else {
        numRowForThread = (numRowA / NUM_OF_THREAD) + (numRowA % NUM_OF_THREAD);
    }
    myWorker[j] = new Worker(startRow, startRow+numRowForThread,matA,matB);
    myWorker[j].start();
    startRow += numRowForThread;
}

for (Worker worker : myWorker) {
    try {
        worker.join();
    } catch (InterruptedException e) {

    }
  }
  return matC;
 }

private static class Worker extends Thread {

private int startRow, stopRow;
private Mat matA, matB;

public Worker(int startRow, int stopRow, Mat matA, Mat matB) {
    super();
    this.startRow = startRow;
    this.stopRow = stopRow;
    this.matA = matA;
    this.matB = matB;
}

@Override
public void run() {
    for (int i = startRow; i < stopRow; i++) {
        for (int j = 0; j < matB.getNColumns(); j++) {
            double sum = 0;
            for (int k = 0; k < matA.getNColumns(); k++) {
                sum += matA.get(i, k) * matB.get(k, j);
            }
            matC.set(i, j, sum);
        }
    }
  }
}
公共类MatMulConcur{
线程的私有最终静态int NUM=1;
专用静态matC;
公共静态matmul(Mat matA、matB){
matC=新Mat(matA.getNRows(),matB.getNColumns());
返回mul(matA、matB);
}
专用静态Mat mul(Mat matA、matB){
int numRowForThread;
int numRowA=matA.getNRows();
int startRow=0;
Worker[]myWorker=新的Worker[NUM_OF_线程];
对于(int j=0;jif(j使用多线程主要不是为了性能,而是为了并行化。不过,在某些情况下,并行化可以提高性能

您的计算机没有无限的资源。添加越来越多的线程会降低性能。这就像启动越来越多的应用程序一样,当您启动另一个程序时,您不会期望一个程序运行得更快,如果它运行得更慢,您可能不会感到惊讶


在某一点上,性能将保持不变(您的计算机仍有资源来处理需求),但在某个时候,您的计算机达到了最大处理能力,性能将下降。这正是您的结果所显示的。性能在1或10个线程中保持不变,然后稳步下降。

人们认为使用多个线程将自动(神奇地!)使任何计算速度加快。这不是so1

有许多因素可能会使多线程加速速度低于您的预期,或者确实会导致速度减慢

  • 具有N个核(或超线程)的计算机的计算速度最多是具有1个核的计算机的N倍。这意味着当您有T个线程,其中T>N时,计算性能将限制在N。(除此之外,线程会因时间切片而取得进展。)

  • 计算机具有一定数量的内存带宽;即,它每秒只能在主内存上执行一定数量的读/写操作。如果您的应用程序的需求超过了内存子系统所能实现的,它将暂停(几纳秒)。如果有多个内核同时执行多个线程,那么重要的是总需求

  • 处理共享变量或数据结构的典型多线程应用程序将使用
    volatile
    或显式同步来实现这一点。这两种方法都会增加对内存系统的需求

  • 当使用显式同步时,两个线程希望同时持有一个锁,其中一个线程将被阻止。此锁争用会降低计算速度。事实上,如果锁上过去存在争用,则计算可能会降低速度

  • 创建线程的成本很高。即使从线程池中获取现有线程的成本也相对较高。如果使用该线程执行的任务太小,安装成本可能会超过可能的加速

  • 还有一个问题是,您可能会在编写糟糕的基准测试时遇到问题;例如,在进行计时测量之前,JVM可能没有正确预热


    您的问题中没有足够的细节来确定上述哪些因素可能会影响应用程序的性能。但这可能是1 2和5的组合…取决于使用的内核数量、CPU内存缓存的大小、矩阵的大小以及其他因素



    1-事实上,如果这是真的,那么我们就不需要购买具有大量内核的计算机。我们可以使用越来越多的线程。如果你有足够的内存,你可以在一台机器上进行无限量的计算。比特币挖掘将是一件轻而易举的事。当然,在一定大小的数组/numb上它不是真的线程的数量越多,线程消耗的资源越多,性能就会下降。可能你应该拥有的最大线程数量等于你CPU中的内核数量。为什么你会对此感到惊讶?你的计算机没有无限的资源,当然,当你继续增加线程数量时,性能会下降。好吧,有一个e添加更多线程时响应良好的问题,但数组乘法通常不是问题之一。分析问题和选择的解决方案以了解正确的线程模型非常重要。不同的解决方案所需的线程数可能会有很大差异。具有X核的CPU只能并行完成X个任务。I如果您添加更多线程,线程调度程序将有更多线程需要管理。在您的情况下,一种可能更有效的方法是缓存线程池或固定线程池,其大小与您的内核数量相同。另一种方法是Fork-Join框架。只需尝试一些方法并选择最佳的替代方法。也许您甚至可以优化当前线程池t代码。谢谢大家提供的信息