Klassen sequentiell und nebenläufig

JennyB

Grünschnabel
Hallo,

ich habe zwei Klassen. Die eine berechnet die Quadrate von Zahlen und die andere prüft ob es sich um Primzahlen handelt.

Diese möchte ich nun gerne sequentiell und nebenläufig ausführen. Ich möchte beweisen, dass die nebenläufige Ausführung schneller geht.

Wie mache ich das?

Meine Klasse für die sequentielle Ausführung sieht so aus:
Code:
    public static void main(final String[] args) {
        final long start = System.nanoTime();
        execute();
        final long end = System.nanoTime();
        System.out.println("Sequentielle Ausführung: " + (end - start));
    }

    private static void execute() {
        final Square square = new Square();
        final Prime prime = new Prime();
        final int squareNumber = 100;
        final int runs = 500;

        for (int i = 0; i < runs; i++) {
            for (int j = 0; j < squareNumber; j++) {
                square.calc(j);
                prime.calc(j);
            }
        }

    }

Der Code für die nebenläufige Ausführung:
Code:
     public static void main(final String[] args) {
        final long start = System.nanoTime();
        execute();
        final long end = System.nanoTime();
        System.out.println("Nebenläufige Ausführung: " + (end - start));
    }

    private static void execute() {
        final Square square = new Square();
        final Prime prime = new Prime();
        final int numberOfThreads = 500;
        final int squarePerThread = 100;

        final Runnable runnable = new Runnable() {
            public void run() {
                for (int i = 0; i < squarePerThread; i++) {
                    square.calc(i);
                }
            }
        };

        final Runnable primeRun = new Runnable() {
            public void run() {
                for (int i = 0; i < squarePerThread; i++) {
                    prime.calc(i);
                }
            }
        };

        for (int i = 0; i < numberOfThreads; i++) {
            final Thread thread = new Thread(runnable);
            final Thread primeT = new Thread(primeRun);
            thread.start();
            primeT.start();
         
        }
    }

Die sequentielle Ausführung ist hier schneller als die nebenläufige. Ist das Normal? Was mache ich falsch
 
1. hast du überhaupt einen Multi Core CPU?

2. IMHO: Du erstellst viel zu viele Threads(500 für jeden), ohne das die vorherigen wahrscheinlich fertig sind.....welche CPUs soll die alle abarbeiten....da ist logisch, dass alleine der overhead dich bremst.
 
Zu 1.: Ich habe gelesen, dass man dafür nicht zwingend eine Multi Core CPU benötigt.
Zu 2.: Ja ich glaube da liegt der Fehler. Zu viele Threads. Bei 10000 Zahlen und ab 8 Threads ist die nebenläufige Anwendung schneller!

Noch eine andere Frage:

Nachdem ich die Threads gestartet habe, mache ich auf jeden Thread ein join() damit ich die Geschwindigkeit der Anwendung messen kann. Sonst ist die Main Methode fertig und die Threads laufen noch. Ich warte quasi bis die Threads fertig sind. Kann ich das auch irgendwie anders machen? Ich würde nämlich sagen, das nimmt ziemlich viel Zeit weg.
 
@Anime
Seit wann braucht man für Nebenläufigkeit mehrere CPUs? Dein Windows kann doch sicher auch Multitasking, oder?

@Jenny
Du brauchst keine 500 Threads. Es reicht für jede berechnung einen Thread zu machen. Wirf die letzte Schleife (die über numberOfThreads) Weg und heb die squarePerThread etwas an, bzw. expeimentier mit der Zahl. Ich würde erwarten, dass mit größeren squarePerThread auch der Geschwindigkeitunterschied zwischen den Ausführungsvarianten signifikanter wird.

Es ist auch von Vorteil einfach beide Ausführungsvarianten in ein Programm zu werfen und dann halt erst das ganze einmal sequenziell und dann parallel auszuführen. Damit ersparst du dir etwaige Ungenauigkeiten durch Speicherallokation usw.

Gruß
Ollie
 
@Anime
Seit wann braucht man für Nebenläufigkeit mehrere CPUs? Dein Windows kann doch sicher auch Multitasking, oder?
Ja, Windows kann Dinge "gleichzeitig". Aber eine CPU eben nicht^^
Macht sich daher ein signifikanter Geschwindigkeitsvorteil nicht erst dadurch bemerkbar? (Zumindest wenn es CPU lastig ist)

:offtopic::offtopic::offtopic:
Windows ist aber eh nicht so gut mit verteilen von Prozessen auf mehrere Cores.
http://www.golem.de/0705/52474.html
Microsoft-Manager Ty Carlson mit den Worten, Vista sei "gestaltet, um auf 1, 2 und vielleicht 4 Prozessoren" zu laufen.
 
Wenn ich diese Schleife über numberOfThreads entferne (sowohl beim nebenläufigen als auch beim sequentiellen Code) und die squarePerThreads anhebe, ist das sequentielle Programme wieder schneller. Ich kann mir das nicht erklären...
 
Mir ist Windows herzlich egal. Fakt ist, dass Nebenläufigkeit NICHT von einem Mehrkernprozessor abhängt. Deswegen fand ich deine Anmerkung einfach nur verwirrend und hab mich gefragt, was du uns damit fragen wolltest.

Gruß
Ollie
 
Nimm mal die Deklarationen den Runnables in die main methode und benutze sie nur in execute(). Vermutlich ist das instantiieren der zwei Runnables recht teuer im Vergleich zu deinen Mathematischen Operationen. Kannst du die evtl ein wenig künstlich "verlängern" (Thread.sleep() zum simulieren von einer teuren Operation)?

Gruß
Ollie
 
Super Idee mit dem Thread.sleep() in den Berechnungen. Nun ist auch schon bei einer kleinen Menge an Zahlen ersichtlich, dass die nebenläufige Berechnung schneller ist!

Ein großes DANKE!! :)
 
Zurück