gpt4 book ai didi

java - 多线程矩阵乘法性能问题

转载 作者:行者123 更新时间:2023-11-30 02:11:09 28 4
gpt4 key购买 nike

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

我运行了这个程序 1,10,20,...,100 个线程,但性能却在下降。以下是时间表

  1. 线程 1 需要 18 毫秒
  2. 线程 10 需要 18 毫秒
  3. 线程 20 需要 35 毫秒
  4. 线程 30 需要 38 毫秒
  5. 线程 40 需要 43 毫秒
  6. 线程 50 需要 48 毫秒
  7. 线程 60 需要 57 毫秒
  8. 线程 70 需要 66 毫秒
  9. 线程 80 需要 74 毫秒
  10. 线程 90 需要 87 毫秒
  11. 线程 100 需要 98 毫秒

有什么想法吗?

最佳答案

人们认为使用多线程会自动(神奇地!)使任何计算速度更快。事实并非如此1

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

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

  2. 计算机有一定的内存带宽;即它每秒只能在主存储器上执行一定数量的读/写操作。如果您的应用程序的需求超出了内存子系统可以实现的范围,它将停止(几纳秒)。如果有多个核心同时执行多个线程,那么聚合需求才是最重要的。

  3. 处理共享变量或数据结构的典型多线程应用程序将使用 volatile 或显式同步来执行此操作。这两者都增加了对内存系统的需求。

  4. 当使用显式同步并且两个线程想要同时持有锁时,其中一个线程将被阻塞。这种锁争用会减慢计算速度。事实上,如果过去存在锁争用,计算可能会变慢。

  5. 线程创建的成本很高。即使从线程池获取现有线程也可能相对昂贵。如果您使用线程执行的任务太小,设置成本可能会超过可能的加速。

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

<小时/>

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

<小时/>

1 - 事实上,如果这是真的,那么我们就不需要购买具有大量内核的计算机。我们可以使用越来越多的线程。如果您有足够的内存,您可以在一台机器上执行无限量的计算。比特币挖矿将是一件轻而易举的事。当然,这不是真的

关于java - 多线程矩阵乘法性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50082047/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com