Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何并行化高斯消去算法?_Java_C_Multithreading_Pthreads_Gaussian - Fatal编程技术网

Java 如何并行化高斯消去算法?

Java 如何并行化高斯消去算法?,java,c,multithreading,pthreads,gaussian,Java,C,Multithreading,Pthreads,Gaussian,我的任务是并行化这个算法: public long GEAlgorithmSequential() { long begin = System.nanoTime(); for (int row = 0; row < size; row++) { double value = matrix[row][row]; for (int col = row + 1; col < size; col++) { matrix

我的任务是并行化这个算法:

public long GEAlgorithmSequential() {
    long begin = System.nanoTime();

    for (int row = 0; row < size; row++) {
        double value = matrix[row][row];
        for (int col = row + 1; col < size; col++) {
            matrix[row][col] /= value;
        }

        solutionVector[row] /= value;
        matrix[row][row] = 1.0;

        for (int innerRow = row + 1; innerRow < size; innerRow++) {
            double innerValue = matrix[innerRow][row];
            for (int innerCol = row + 1; innerCol < size; innerCol++) {
                //System.out.printf("matrix[%d][%d] (%.2f) -= %.2f * matrix[%d][%d] (%.2f)\n", innerRow, innerCol, matrix[innerRow][innerCol], innerValue, row, innerCol, matrix[row][innerCol]);
                matrix[innerRow][innerCol] -= innerValue * matrix[row][innerCol];
            }
            solutionVector[innerRow] -= matrix[innerRow][row] * solutionVector[row];
            matrix[innerRow][row] = 0.0;
        }
    }

    //PrintMatrix("Upper Triangular Matrix");

    for (int back = size - 1; back >= 0; back--) {
        answers[back] = solutionVector[back];
        for (int i = back - 1; i >= 0; i--) {
            solutionVector[i] -= answers[back] * matrix[i][back];
        }
    }
    return System.nanoTime() - begin;
}
public long GEAlgorithmSequential(){
long begin=System.nanoTime();
对于(int row=0;row=0;back--){
答案[返回]=解向量[返回];
对于(int i=back-1;i>=0;i--){
解向量[i]=答案[back]*矩阵[i][back];
}
}
return System.nanoTime()-开始;
}
我理解这个算法:第一部分取一行,将行中的所有其他部分除以对角线值,得到对角线1

第二部分,两个循环,零代表对角线下的所有内容

最后一部分,在PrintMatrix调用之后,我们进行反向替换,最终答案向量位于solutionVector中

我被告知这部分是可并行的:

for (int innerRow = row + 1; innerRow < size; innerRow++) {
    double innerValue = matrix[innerRow][row];
    for (int innerCol = row + 1; innerCol < size; innerCol++) {
        matrix[innerRow][innerCol] -= innerValue * matrix[row][innerCol];
    }
    solutionVector[innerRow] -= matrix[innerRow][row] * solutionVector[row];
    matrix[innerRow][row] = 0.0;
}
for(int innerRow=row+1;innerRow
为了进一步解释这一部分,它将逐行进行,对整行(每列,即内部循环)执行操作

我的第一个想法是为每一行启动一个线程,因为每一行都是独立的,只依赖于我们刚刚设置为1的主“行”,我们不接触它

所以我这样做了:

for (int innerRow = row + 1; innerRow < size; innerRow++) {
    threads[innerRow] = new SubMatrixThread(this, innerRow, row);
    threads[innerRow].start();
}

for (int innerRow = row + 1; innerRow < size; innerRow++) {
    try {
        threads[innerRow].join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
for(int innerRow=row+1;innerRow
SubstryXthread是:

@Override
public void run() {
    double innerValue = m.GetMatrix()[innerRow][row];
    for (int innerCol = row + 1; innerCol < size; innerCol++) {
        m.GetMatrix()[innerRow][innerCol] -= innerValue * m.GetMatrix()[row][innerCol];
    }
    m.GetSolutionVector()[innerRow] -= m.GetMatrix()[innerRow][row] * m.GetSolutionVector()[row];
    m.GetMatrix()[innerRow][row] = 0.0;
}
@覆盖
公开募捐{
double innerValue=m.GetMatrix()[innerRow][row];
对于(int innerCol=row+1;innerCol
m.GetMatrix()和m.GetSolutionVector()是同步方法,它们从矩阵对象返回矩阵和向量

在完成所有这些之后,线程应用程序比顺序应用程序花费的时间要长得多。例如,在512x512矩阵上,顺序算法需要0.039秒,线程算法需要>10秒。矩阵越大,时机就越差。IE sequential 4098x4098耗时约24秒,线程化完成时间超过5分钟(之后我才停止)

更多信息:我第一次用C启动这个程序,遇到了同样的问题,线程(来自pthreads)比sequential花费的时间更长。我的代码开始变得疯狂,因为我试图弄明白这一点,所以我用Java编写了它,以使自己更轻松

我上面描述的方法为每一行启动一个线程。我还只启动了两个线程,并将内部for循环分成两部分,而不是n部分。我在那里也遇到了同样的问题

我在Windows桌面上用IntelliJ运行Java,在Linux发行版上运行C程序,这两个应用程序都有同样的问题


有人知道我遗漏了什么吗?

问题很可能就在这里:

m.GetMatrix()和m.GetSolutionVector()是同步方法

这意味着,对于每一个操作,您都会调用同步机制,这将导致巨大的性能损失

只要让它们成为常规方法就足够了。我没有彻底检查算法,但应该没有竞争条件,因为行是独立的


更不用说同步它们在另一个意义上是无用的:如果存在竞争条件的风险,你就不会受到保护:你得到了矩阵,但你在保护结束后更新了它的内容(你在退出这些方法后更新了矩阵,所以你不再有锁).

您没有意识到创建线程和启动线程的开销非常大。使用线程池。创建一个执行器的简单方法是

您可以提交可运行实例或可调用实例

如果只想等待计算完成,而不从计算中获取返回值,可以使用Runnable:

Runnable r = ...;
Future<?> f = threadPool.submit(r);
因为Runnable没有返回值,所以忽略返回值


您还可以实现
Callable
,在计算结束时返回一个值,并在
submit
调用返回的将来使用
f.get()
检索该值。

您使用的线程太多,无法满足您的需要。使用5
Runnable r = ...;
Future<?> f = threadPool.submit(r);
f.get();