Using classes from the java.util.Concurrent package to multiply matrices on android?

Asked

Viewed 384 times

2

I was doing this program to multiply matrices, I saw that it correctly calculates the result, but there is no performance gain by putting more threads, often even worse performance despite running on a smartphone 4 quad core. I wonder if I’m doing something very wrong (I don’t know much about parallelism) or this problem isn’t worth so much being parallelized.

The program was based on this question : https://stackoverflow.com/questions/5484204/parallel-matrix-multiplication-in-java-6

Thank you.

   public class MainActivity extends Activity {

private int SIZE;
private static final int THRESHOLD = 64;
private  int MAX_THREADS;
private double valor;
private ExecutorService executor = null;
private TextView textTamanhoMatrizes;

private TextView multiplicacaoConcluida;
private TextView textQuantidadeThreads;
private TextView textValorElementos;
private EditText valorElementos;
private EditText tamanhoMatrizes;

private EditText quantidadeThreads;
private TextView textTempoExecucao;
private TextView tempoExecucao;
private Button buttonMultiplicarMatrizes;

double matrizA[][] ;
double matrizB[][]; 
double matrizResultante[][];

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    textTamanhoMatrizes = (TextView) findViewById(R.id.textTamanhoMatrizes);
    textQuantidadeThreads = (TextView) findViewById(R.id.textQuantidadeThreads);
    tamanhoMatrizes = (EditText) findViewById(R.id.tamanhoMatrizes);
    textValorElementos = (TextView)findViewById(R.id.textValorElementos);
    quantidadeThreads = (EditText) findViewById(R.id.quantidadeThreads);
    valorElementos = (EditText) findViewById(R.id.valorElementos);
    textTempoExecucao = (TextView) findViewById(R.id.textTempoExecucao);
    tempoExecucao = (TextView) findViewById(R.id.tempoExecucao);
    buttonMultiplicarMatrizes = (Button) findViewById(R.id.buttonMultiplicarMatrizes);
    multiplicacaoConcluida = (TextView) findViewById(R.id.multiplicacaoConcluida);
    multiplicacaoConcluida.setVisibility(View.INVISIBLE);
    textTempoExecucao.setVisibility(View.INVISIBLE);
    tempoExecucao.setVisibility(View.INVISIBLE);        
    buttonMultiplicarMatrizes.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            SIZE = Integer.valueOf(tamanhoMatrizes.getText().toString());
            MAX_THREADS = Integer.valueOf(quantidadeThreads.getText().toString());
            valor = Double.valueOf(valorElementos.getText().toString());
            matrizA = new double[SIZE][SIZE];
            matrizB = new double[SIZE][SIZE];
            matrizResultante = new double[SIZE][SIZE];
            init(matrizA, matrizB, SIZE, valor);

            executor = Executors.newFixedThreadPool(SIZE);
            Long tempoInicial =0L;
            Long tempoFinal=0L;
            MatrixMultiplyTask mainTask =  new MatrixMultiplyTask(matrizA, 0, 0, matrizB, 0, 0, matrizResultante, 0, 0, SIZE);
            tempoInicial = android.os.SystemClock.uptimeMillis();
             Future future = executor.submit(mainTask);  
             try {
                    future.get();
                    tempoFinal = android.os.SystemClock.uptimeMillis();
                    multiplicacaoConcluida.setVisibility(View.VISIBLE);
                    textTempoExecucao.setVisibility(View.VISIBLE);

                    tempoExecucao.setText((tempoFinal-tempoInicial)+" ms");
                    tempoExecucao.setVisibility(View.VISIBLE);
                    Toast.makeText(getBaseContext(), "Início : "+tempoInicial+" Fim: "+tempoFinal+" Total: "+(tempoFinal-tempoInicial)+ "ms", Toast.LENGTH_LONG).show();
                } catch (Exception e) {
                    System.out.println("Error: " + e.getMessage());
                }
            if (matrizA == null || matrizB == null) {
                Toast.makeText(getBaseContext(), "Erro ao gerar matriz A ou matriz B", Toast.LENGTH_SHORT).show();
                return;
            }

        }
    });


}




      static void init(double[][] matrizA2, double[][] matrizB2, int n, double valor) {
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            matrizA2[i][j] = valor;
            matrizB2[i][j] = valor;
        }
    }
}

    public class Seq implements Runnable {

    private final MatrixMultiplyTask a;
    private final MatrixMultiplyTask b;

    public Seq(MatrixMultiplyTask a, MatrixMultiplyTask b) {
        this.a = a;
        this.b = b;     
    }

    public void run() {
        a.run();
        b.run();
    }   
}




     private class MatrixMultiplyTask implements Runnable {
        private final double[][] A; // Matrix A
        private final int aRow; // first row of current quadrant of A
        private final int aCol; // first column of current quadrant of A

        private final double[][] B; // Similarly for B
        private final int bRow;
        private final int bCol;

        private final double[][] C; // Similarly for result matrix C
        private final int cRow;
        private final int cCol;

        private final int size;

        public MatrixMultiplyTask(double[][] A, int aRow, int aCol, double[][] B,
                int bRow, int bCol, double[][] C, int cRow, int cCol, int size) {

            this.A = A;
            this.aRow = aRow;
            this.aCol = aCol;
            this.B = B;
            this.bRow = bRow;
            this.bCol = bCol;
            this.C = C;
            this.cRow = cRow;
            this.cCol = cCol;
            this.size = size;
        }   

        public void run() {

            //System.out.println("Thread: " + Thread.currentThread().getName());

            if (size <= THRESHOLD) {
                multiplyStride2();
            } else {

                int h = size / 2;

                        Seq seq1 = new Seq(new MatrixMultiplyTask(A,
                                aRow, aCol, // A11
                                B, bRow, bCol, // B11
                                C, cRow, cCol, // C11
                                h),

                        new MatrixMultiplyTask(A, aRow, aCol + h, // A12
                                B, bRow + h, bCol, // B21
                                C, cRow, cCol, // C11
                                h));

                        Seq seq2 = new Seq(new MatrixMultiplyTask(A,
                                aRow, aCol, // A11
                                B, bRow, bCol + h, // B12
                                C, cRow, cCol + h, // C12
                                h),

                        new MatrixMultiplyTask(A, aRow, aCol + h, // A12
                                B, bRow + h, bCol + h, // B22
                                C, cRow, cCol + h, // C12
                                h));

                        Seq seq3 = new Seq(new MatrixMultiplyTask(A, aRow
                                + h, aCol, // A21
                                B, bRow, bCol, // B11
                                C, cRow + h, cCol, // C21
                                h),

                        new MatrixMultiplyTask(A, aRow + h, aCol + h, // A22
                                B, bRow + h, bCol, // B21
                                C, cRow + h, cCol, // C21
                                h));

                        Seq seq4 = new Seq(new MatrixMultiplyTask(A, aRow
                                + h, aCol, // A21
                                B, bRow, bCol + h, // B12
                                C, cRow + h, cCol + h, // C22
                                h),

                        new MatrixMultiplyTask(A, aRow + h, aCol + h, // A22
                                B, bRow + h, bCol + h, // B22
                                C, cRow + h, cCol + h, // C22
                                h));            



                final FutureTask s1Task = new FutureTask(seq2, null);
                final FutureTask s2Task = new FutureTask(seq3, null);
                final FutureTask s3Task = new FutureTask(seq4, null);

                executor.execute(s1Task);
                executor.execute(s2Task);
                executor.execute(s3Task);

                seq1.run();
                s1Task.run();
                s2Task.run();
                s3Task.run();

                try {
                    s1Task.get();
                    s2Task.get();
                    s3Task.get();
                } catch (Exception e) {
                    System.out.println("Error: " + e.getMessage());
                    executor.shutdownNow();
                }       
            }       
        }       


      public void multiplyStride2() {
            for (int j = 0; j < size; j += 2) {
                for (int i = 0; i < size; i += 2) {

                    double[] a0 = A[aRow + i];
                    double[] a1 = A[aRow + i + 1];

                    float s00 = 0.0F;
                    float s01 = 0.0F;
                    float s10 = 0.0F;
                    float s11 = 0.0F;

                    for (int k = 0; k < size; k += 2) {

                        double[] b0 = B[bRow + k];

                        s00 += a0[aCol + k] * b0[bCol + j];
                        s10 += a1[aCol + k] * b0[bCol + j];
                        s01 += a0[aCol + k] * b0[bCol + j + 1];
                        s11 += a1[aCol + k] * b0[bCol + j + 1];

                        double[] b1 = B[bRow + k + 1];

                        s00 += a0[aCol + k + 1] * b1[bCol + j];
                        s10 += a1[aCol + k + 1] * b1[bCol + j];
                        s01 += a0[aCol + k + 1] * b1[bCol + j + 1];
                        s11 += a1[aCol + k + 1] * b1[bCol + j + 1];
                    }

                    C[cRow + i][cCol + j] += s00;
                    C[cRow + i][cCol + j + 1] += s01;
                    C[cRow + i + 1][cCol + j] += s10;
                    C[cRow + i + 1][cCol + j + 1] += s11;
                }
            }           
        }
    }

}

1 answer

1

I suggest you withdraw:

s1Task.run();
s2Task.run();
s3Task.run();

because that is the task of the executor.

You’re running the same thing twice.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.