Wie sichergestellt werden Java-threads auf verschiedenen Kerne

Schreibe ich eine multi-threaded-Applikation in Java, um zur Verbesserung der Leistung über die sequentielle version. Es ist eine parallel-version der dynamischen Programmierung Lösung des 0/1 knapsack problem. Ich habe einen Intel Core 2 Duo, sowohl mit Ubuntu und Windows 7 Professional auf verschiedenen Partitionen. Ich bin auch unter Ubuntu.

Mein problem ist, dass die parallele version tatsächlich länger dauert als die sequentielle version. Ich denke, dies kann sein, weil die threads sind alle zugeordnet, die den gleichen kernel thread oder, dass Sie verteilt werden, auf dem gleichen Kern. Gibt es eine Möglichkeit, ich könnte dafür sorgen, dass jedes Java-thread-Karten auf einen separaten core?

Habe ich andere Beiträge gelesen über dieses problem, aber nichts scheint zu helfen.

Hier ist das Ende von main() und alle von run() für die KnapsackThread Klasse (extends Thread). Beachten Sie, dass Sie die Art, wie ich mit in Scheiben schneiden und extra zu berechnen myLowBound und myHiBound sicherzustellen, dass jeder thread überschneiden sich nicht in der Domäne des dynProgMatrix. Es gibt also keine race conditions.

    dynProgMatrix = new int[totalItems+1][capacity+1];
    for (int w = 0; w<= capacity; w++)
        dynProgMatrix[0][w] = 0;
    for(int i=0; i<=totalItems; i++)
        dynProgMatrix[i][0] = 0;
    slice = Math.max(1,
            (int) Math.floor((double)(dynProgMatrix[0].length)/threads.length));
    extra = (dynProgMatrix[0].length) % threads.length;

    barrier = new CyclicBarrier(threads.length);
    for (int i = 0; i <  threads.length; i++){
        threads[i] = new KnapsackThread(Integer.toString(i));
    }
    for (int i = 0; i < threads.length; i++){
        threads[i].start();
    }

    for (int i = 0; i < threads.length; i++){
        try {
            threads[i].join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public void run(){
    int myRank = Integer.parseInt(this.getName());

    int myLowBound;
    int myHiBound;

    if (myRank < extra){
        myLowBound = myRank * (slice + 1);
        myHiBound = myLowBound + slice;
    }
    else{
        myLowBound = myRank * slice + extra;
        myHiBound = myLowBound + slice - 1;
    }

    if(myHiBound > capacity){
        myHiBound = capacity;
    }

    for(int i = 1; i <= totalItems; i++){
        for (int w = myLowBound; w <= myHiBound; w++){

            if (allItems[i].weight <= w){
               if (allItems[i].profit + dynProgMatrix[i-1][w-allItems[i].weight]
                        > dynProgMatrix[i-1][w])
                {
                    dynProgMatrix[i][w] = allItems[i].profit +
                                      dynProgMatrix[i-1][w- allItems[i].weight];
                }
                else{
                    dynProgMatrix[i][w] = dynProgMatrix[i-1][w];
                }
            }
            else{
                dynProgMatrix[i][w] = dynProgMatrix[i-1][w];
            }
        }
        //now place a barrier to sync up the threads
        try {
            barrier.await(); 
        } catch (InterruptedException ex) { 
            ex.printStackTrace();
            return;
        } catch (BrokenBarrierException ex) { 
            ex.printStackTrace(); 
            return;
        }
    }
}

Update:

Ich geschrieben habe, eine andere version der Ranzen verwendet brute-force. Diese version hat sehr wenig Synchronisation, da brauche ich nur ein update bestSoFar Variablen am Ende von einen einzigen thread der Ausführung. Daher kann jeder thread ziemlich viel ausführen sollte vollständig in parallele, außer, dass die kleinen kritischen Abschnitt am Ende.

Lief ich dies gegenüber der sequentiellen brute-force-und trotzdem dauert es länger. Ich sehe keine andere Erklärung als die, dass meine threads werden sequenziell ausgeführt werden, weil Sie entweder zugeordnet werden, um den gleichen Kern oder der gleichen nativen thread.

Hat jemand eine Einsicht?

Willkommen in der Welt von parallel-computing! Es ist sehr wahrscheinlich, dass Ihre threads sind in der Tat abgebildet werden, um verschiedene Kerne, und es ist auch wahrscheinlich, dass Ihr Programm wäre in der Tat schneller (zwar immer noch langsamer als die sequentielle version) wenn Sie waren auf dem gleichen Kern. Wo hast du den parallel-knapsack-Algorithmus aus? Ist es entworfen, um zu reduzieren shared-memory-Kommunikation (einschließlich Verriegelung) so viel wie möglich?
Es könnte nützlich sein, wenn Sie post einen link zu Ihrer KnapsackThread code, und sagen etwas über die Menge der threads, die Sie verwenden. Mehr als 4-8 threads, die möglicherweise ein problem auf einem core duo und synchronisierte Blöcke können bringen jeden nieder, der code 🙂
auch welche VM benutzt du, Sonne, die auf windows und openjdk auf ubuntu, oder genießen Sie die Sonne auf beiden?
Ich schrieb meine version aus einer sequentiellen version von einer anderen person. Es sperrt nicht den Zugriff auf den freigegebenen 2d-array, Tue ich jedoch sicherzustellen, dass jeder thread nur schreibt, um verschiedene indecies des 2d-array, um Wettlaufsituationen zu vermeiden. Ich bin mit einem thread pro core, die ich tun von: private static KnapsackThread threads[] = new KnapsackThread[ Laufzeit.getRuntime().availableProcessors() ]; }
Ich weiß nicht, was VM verwende ich außerdem 1.6. Ich lief die java -version im terminal: java version "1.6.0_16" Java(TM) SE Runtime Environment (build 1.6.0_16-b01) Java HotSpot(TM) Server VM (build 14.2-b01, mixed mode)

InformationsquelleAutor KBP | 2009-12-13

Schreibe einen Kommentar