Как обеспечить работу потоков Java на разных ядрах

Я пишу многопоточное приложение на Java для повышения производительности по сравнению с последовательной версией. Это параллельная версия решения динамического программирования для задачи о ранце 0/1. У меня Intel Core 2 Duo с Ubuntu и Windows 7 Professional на разных разделах. Я бегу в Ubuntu.

Моя проблема в том, что параллельная версия на самом деле занимает больше времени, чем последовательная версия. Я думаю, что это может быть связано с тем, что все потоки отображаются в один и тот же поток ядра или что они распределены одному и тому же ядру. Есть ли способ, которым я мог бы гарантировать, что каждый поток Java отображается на отдельное ядро?

Я читал другие посты об этой проблеме, но, похоже, ничего не помогает.

Здесь конец main () и все run () для класса KnapsackThread (который расширяет Thread). Обратите внимание, что они, как я использую slice и extra для вычисления myLowBound, и myHiBound гарантируют, что каждый поток не будет перекрываться в домене dynProgMatrix. Поэтому не будет гоночных условий.

    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;
        }
    }
}
Обновить:

Я написал еще одну версию рюкзака, который использует грубую силу. Эта версия имеет очень мало синхронизации, потому что мне нужно обновить переменную bestSoFar только в конце выполнения одного потока. Следовательно, каждый поток должен выполняться полностью параллельно, за исключением небольшого критического раздела в конце.

Я управлял этим против последовательной грубой силы, и все же это занимает больше времени. Я не вижу другого объяснения, кроме того, что мои потоки выполняются последовательно, либо потому, что они сопоставлены с тем же ядром или с тем же собственным потоком.

У кого-нибудь есть понимание?

Ответы на вопрос(3)

Ваш ответ на вопрос