Plusieurs threads java sur un Mac 2 cœurs-Lent


J'ai écrit le code suivant pour mon cours OS et j'ai obtenu des résultats étranges. Le code crée x threads et les exécute simultanément, afin de multiplier deux matrices carrées. Chaque thread multipliera les lignes Number_of_rows/Number_of_threads des matrices d'entrée.

Lors de son exécution sur une matrice 1024X1024, avec 1...8 threads, je comprends que la multiplication la plus rapide se produit lorsque vous utilisez un seul thread. Je m'attendrais à ce qu'un MacBook pro avec processeur i5 (2 cœurs) utiliser les deux cœurs et qui donnera des résultats plus rapides lors de l'utilisation de deux fils. Le temps d'exécution va d'environ ~ 9,2 secondes en utilisant un thread, ~ 9,6 secondes à 27 secondes en utilisant 8.

Une idée de pourquoi cela se produit?

BTW, quelques choses sur le code:

A. Supposons que les deux matrices ont des dimensions identiques et sont carrées.

B. Supposons que nombre de threads

public class MatrixMultThread implements Runnable {
    final static int MATRIX_SIZE = 1024;
    final static int MAX_THREADS = MATRIX_SIZE;
    private float[][] a;
    private float[][] b;
    private float[][] res;
    private int startIndex;
    private int endIndex;


public MatrixMultThread(float[][] a, float[][]b, float[][] res, int startIndex, int endIndex) {
    this.a = a;
    this.b = b;
    this.res = res;
    this.startIndex = startIndex;
    this.endIndex = endIndex;
}


public void run() {
    float value = 0;
    for (int k = startIndex; k < endIndex; k++) {
        for (int i = 0; i < a.length; i++) {
            for (int j = 0; j < a.length; j++) {
                value += a[k][j]*b[j][i];
            }
            res[k][i] = value;
            value = 0;
        }
    }
}


public static float[][] mult(float[][] a, float[][] b, int threadCount){

    // Get number of rows per each thread.
    int rowsPerThread = (int) Math.ceil(MATRIX_SIZE / threadCount);
    float[][] res = new float[MATRIX_SIZE][MATRIX_SIZE];

    // Create thread array
    Thread[] threadsArray = new Thread[threadCount];
    int rowCounter = 0;
    for (int i = 0; i < threadCount; i++) {
        threadsArray[i] = new Thread(new MatrixMultThread(a,b,res,rowCounter, Math.max(rowCounter + rowsPerThread, MATRIX_SIZE)));
        threadsArray[i].start();
        rowCounter += rowsPerThread;
    }


    // Wait for all threads to end before finishing execution.
    for (int i = 0; i < threadCount; i++) {
        try {
            threadsArray[i].join();
        } catch (InterruptedException e) {
            System.out.println("join failed");
        }
    }
    return res;
}


public static void main(String args[]) {
    // Create matrices and random generator
    Random randomGenerator = new Random();
    float[][] a = new float[MATRIX_SIZE][MATRIX_SIZE];
    float[][] b = new float[MATRIX_SIZE][MATRIX_SIZE];

    // Initialize two matrices with initial values from 1 to 10.
    for (int i = 0; i < a.length; i++) {
        for (int j = 0; j < a.length; j++) {
            a[i][j] = randomGenerator.nextFloat() * randomGenerator.nextInt(100);
            b[i][j] = randomGenerator.nextFloat() * randomGenerator.nextInt(100);
        }
    }
    long startTime;
    for (int i = 1; i <= 8; i++) {
        startTime = System.currentTimeMillis();
        mult(a,b,i);
        System.out.println("Total running time is: " + (System.currentTimeMillis() - startTime) + " ms");
    }
}

}

Author: elmekiesIsrael, 2015-03-29

1 answers

Tout d'abord, un peu de journalisation aide. J'ai fait la journalisation pour cela et j'ai découvert un bogue dans votre logique.

Voici le journal

Starting execution for thread count: 1
Start index: 0
End index: 1024
Starting execution: MatrixMultiplier: 0
Ending executionMatrixMultiplier: 0
Total running time is: 6593 ms


Starting execution for thread count: 2
Start index: 0
End index: 1024  <------ This is the problem area
Start index: 512
End index: 1024
Starting execution: MatrixMultiplier: 1
Starting execution: MatrixMultiplier: 0

Votre premier thread dans toutes les itérations effectue une multiplication entière à chaque fois. C'est pourquoi vous ne voyez pas de résultats. Trouver le bug.

 0
Author: Narendra Pathai, 2015-03-29 08:37:50