将矩阵分成两半并且并行乘法:本地和远程

时间:2014-11-11 13:53:10

标签: java multithreading matrix parallel-processing

我已经为我的作业工作了几天。我需要使用并行处理技术将两个矩阵相乘。

我做以下实验:

  1. 我使用单线程在一台机器上乘以矩阵并计算持续时间
  2. 我使用多线程在一台机器上乘以矩阵并计算持续时间
  3. 我将第一个矩阵水平分成两半,然后将其一半放在我的本地计算机上,剩下的一半放在远程计算机上。
  4. -

    double[][] A = new double[1000][1000];
    double[][] B = new double[1000][1000];
    double[][] C = new double[1000][1000];
    
    
    double[][] A1 = new double[500][1000];
    double[][] A2 = new double[500][1000];
    
    
    double[][] C1 = new double[500][1000];
    double[][] C2 = new double[500][1000];
    
    
    C1 = multiplyLocal(A1, B);
    C2 = multiplyRemote(mat2Str(A2,0,A2.length), mat2Str(B,0,B.length));
    

    因为我无法通过Web方法成功传输double [] []数组,所以我不得不将矩阵转换为String以传输到远程并在multiplyRemote()方法中转换回double[][]数组。计算后,我将结果转换为String并返回客户端,然后客户端再次将其转换为double[][]数组。

    public static double[][] multiplyLocal(final double[][] blockA, final double[][] B) {
    
         final double[][] C1 = new double[blockA.length][blockA[0].length];
    
        final int nThreads = Runtime.getRuntime().availableProcessors();
        final int blockSize = blockA.length / nThreads;
        Thread[] threads = new Thread[nThreads];
    
        for (int n = 0; n < nThreads; n++) {
            final int finalN = n;
            threads[n] = new Thread() {
                @Override
                public void run() {
                    final int beginIndex = finalN * blockSize;
                    final int endIndex = (finalN == (nThreads - 1)) ? blockA.length : (finalN + 1) * blockSize;
                    for (int i = beginIndex; i < endIndex; i++) {
                        for (int j = 0; j < blockA.length; j++) {
                            for (int k = 0; k < blockA[0].length; k++) {
                                C1[i][j] += blockA[i][k] * mB[k][j];
                            }
                        }
                    }
                }
            };
            threads[n].start();
        }
        for (int n = 0; n < nThreads; n++) {
            try {
                threads[n].join();
            } catch (InterruptedException e) {
                System.exit(-1);
            }
        }
    
        return C1; 
    }
    

    这是web方法multiplyRemote

    @WebMethod(operationName = "multiplyRemote")
    public String multiplyRemote(final String blockA, final String B) {
    
        final double[][] mA = str2Mat(blockA);
        final double[][] mB = str2Mat(B);
        final double[][] C2 = new double[mA.length][mA[0].length];
    
        final int nThreads = Runtime.getRuntime().availableProcessors();
        final int blockSize = mA.length / nThreads;
        Thread[] threads = new Thread[nThreads];
    
        for (int n = 0; n < nThreads; n++) {
            final int finalN = n;
            threads[n] = new Thread() {
                @Override
                public void run() {
                    final int beginIndex = finalN * blockSize;
                    final int endIndex = (finalN == (nThreads - 1)) ? mA.length : (finalN + 1) * blockSize;
                    for (int i = beginIndex; i < endIndex; i++) {
                        for (int j = 0; j < mA.length; j++) {
                            for (int k = 0; k < mA[0].length; k++) {
                                C2[i][j] += mA[i][k] * mB[k][j];
                            }
                        }
                    }
                }
            };
            threads[n].start();
        }
        for (int n = 0; n < nThreads; n++) {
            try {
                threads[n].join();
            } catch (InterruptedException e) {
                System.exit(-1);
            }
        }
        //mat2Str(double[][], startIndex, rowCount)   
        return mat2Str(C2, 0 , C2.length);
    }
    

    是的,我在想我是在做第三步。所以我注意到,如果没有完成multiplyLocal()进程,它就不会跳转到下一行。我的意思是远程计算机等待闲置,直到本地完成它的工作。

    我需要将一半的​​进程发送到远程计算机并在本地计算另一半,直到远程结果返回。

    我该怎么做?

1 个答案:

答案 0 :(得分:0)

你应该在另一个线程中运行multiplyLocal(A1,B)。 https://blogs.oracle.com/CoreJavaTechTips/entry/get_netbeans_6