【问题标题】:Java Concurrent - Thread synchronization in Fork/Join - LU decompositionJava Concurrent - Fork/Join 中的线程同步 - LU 分解
【发布时间】:2013-12-06 17:07:54
【问题描述】:

在开发 Java 软件的过程中,我在这里问过 Java Concurrent - no speedUp gained LU algorithm - False sharing? 为什么我没有使用 CyclicBarrier 加速并行化这段代码。

       public void decompose(){
int n = A.length;
for(int k=0; k<n-1;k++) {
    for(int i=k+1; i<n; i++) {
        A[i][k] = A[i][k]/A[k][k];
        for(int j=k+1; j<n; j++) {
            A[i][j] = A[i][j] - A[i][k] * A[k][j];
        }
    }
}
decomposed = true;
}  

算法基本上是做矩阵的高斯归约

经过一些讨论(如果您有兴趣,请查看 cmets),一位用户 (brettw) 使用 Fork/Join Java 框架回复了此解决方案:

    public void decompose()
{
 final Semaphore semaphore = new Semaphore(0);

class Decompose extends RecursiveAction {
    private final int k;

    Decompose(int k) {
        this.k = k;
    }

    protected void compute() {
        final int n = A.length;
        for (int i = k + 1; i < n; i++) {
            A[i][k] = A[i][k] / A[k][k];
            for (int j = k + 1; j < n; j++) {
                A[i][j] = A[i][j] - A[i][k] * A[k][j];
            }
        }

        semaphore.release();
    }
}

ForkJoinPool mainPool = new ForkJoinPool();
for (int k = 0; k < A.length - 1; k++) {
    mainPool.execute(new Decompose(k));
}
semaphore.acquireUninterruptibly(A.length - 1);
}

问题在于该算法没有产生预期的结果,因为没有与工作线程同步(每一行都必须更新所有值以增加k 值)。

我的问题是:

由于我无法预见线程/工作者的数量,您会建议哪种同步策略?

【问题讨论】:

  • 学习更多的英语永远不会太晚!
  • 我认为这不是并行化这个算法的正确方法,因为第n次迭代需要第(n-1)次迭代的结果(矩阵变化)。我想你应该找到另一种并行化策略。
  • 没错,这就是问题每一行都必须更新所有值以增加 k 值 但我真的不知道如何......我试过了一个 AtomicInteger 由所有线程共享,但似乎效果不佳(最低加速)
  • 对,拆分问题的明显方法不起作用,因为它们依赖于能够将问题拆分为独立的块。并行化这似乎很微妙,需要对算法进行一些重新安排。在网络上搜索“并行高斯消去”会发现一些有趣的论文和讲座,其中包括:cs.berkeley.edu/~yelick/cs267_sp07/lectures/lecture12/…

标签: java multithreading concurrency java.util.concurrent matrix-decomposition


【解决方案1】:

您没有按照预期的方式使用 Fork-Join 池。您需要将工作分成小部分。然后分解()每个部分并组合结果。

compute() 需要如下代码:

if (work < max) {
   work left = split left half
   work right = split right half
   fork (left) 
   right.compute()
   left.join()
} 

如果不拆分工作,您将不会使用多个线程。使用信号量单线程的工作,你永远不会看到加速。

查看 API 中使用此框架的示例。

【讨论】:

  • 是的,算法应该“重新设计”,可能叉连接不是我想要的。
猜你喜欢
  • 2014-02-08
  • 1970-01-01
  • 2011-05-15
  • 2013-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多