Cos'è un buon programma parallelo [con thread Java]?


Sto imparando il Thread in Java per creare un programma eseguito in parallelo. Progettare programmi con parallelismo è qualcosa che non ho mai avuto la possibilità di imparare nella mia classe di programmazione scolastica. So come creare thread e farli funzionare, ma non ho idea di come usarli in modo efficiente. Dopotutto so che in realtà non sta usando thread che rendono un programma veloce ma un buon design parallelo. Così ho fatto qualche esperimento per testare le mie conoscenze. Tuttavia, il mio parallelo la versione in realtà funziona più lentamente di una senza precedenti. Comincio a dubitare se ho davvero l'idea. Se potessi essere così gentile, ti dispiacerebbe dare un'occhiata al mio seguente programma:

Ho creato un programma per riempire un array in modo divide-and-conquer (so che Java ha un array.riempi l'utilità, ma voglio solo testare le mie conoscenze in multithreading):

public class ParalledFill
{
    private static fill(final double [] array, 
                        final double value, 
                        final int start, 
                        final int size)
    {
        if (size > 1000) 
        { // Each thread handles at most 1000 elements
            Runnable task = new Runnable() { // Fork the task
                public void run() { 
                    fill(array, value, start, 1000); // Fill the first 1000 elements
            }};
            // Create the thread
            Thread fork = new Thread(task);
            fork.start(); 
            // Fill the rest of the array
            fill(array, value, start+1000, size-1000);
            // Join the task
            try {
                fork.join();
            }
            catch (InterruptedException except)
            {
                System.err.println(except);
            }
        }
        else 
        { // The array is small enough, fill it via a normal loop
            for (int i = start; i < size; ++i)
            array[i] = value;
        }
    } // fill

    public static void main(String [] args)
    {
        double [] bigArray = new double[1000*1000];
        double value = 3;
        fill(bigArray, value, 0, bigArray.length);
    }
}

Ho testato questo programma, ma risulta essere ancora più lento del semplice fare qualcosa come:

for (int i = 0; i < bigArray.length; ++i)
    bigArray[i] = value;

Avevo la mia ipotesi, potrebbe sia che java faccia qualche ottimizzazione per riempire un array usando un ciclo che lo rende molto più veloce della mia versione filettata. Ma a parte questo, sento più fortemente che il mio modo di gestire thread/parallelismo potrebbe essere sbagliato. Non ho mai progettato nulla usando i thread (sempre fatto affidamento sull'ottimizzazione del compilatore o OpenMP in C). Qualcuno potrebbe aiutarmi a spiegare perché la mia versione parallela non è più veloce? Era il programma semplicemente troppo male in termini di progettazione programma parallelo?

Grazie, Xing.

Author: xing_yu, 2013-11-01

1 answers

A meno che tu non abbia più CPU o attività di lunga durata come I/O, immagino che tutto ciò che stai facendo sia il tempo di tagliare tra i thread. Se c'è una singola CPU che ha così tanto lavoro da fare, l'aggiunta di thread non diminuisce il lavoro che deve essere fatto. Tutto quello che finisci per fare è aggiungere overhead a causa del cambio di contesto.

Dovresti leggere "Java Concurrency In Practice". Meglio imparare come fare le cose con il pacchetto di concorrenza moderno piuttosto che i thread grezzi.

 0
Author: duffymo, 2013-11-01 20:42:43