Comment s'assurer que le Java threads s'exécutent sur différents cœurs

Je suis en train d'écrire une application multi-thread en Java afin d'améliorer les performances sur la version séquentielle. C'est une version parallèle de la programmation dynamique de la solution à la 0/1 problème de sac-à-dos. J'ai un processeur Intel Core 2 Duo à la fois avec Ubuntu et Windows 7 Professionnel sur des partitions différentes. Je suis en cours d'exécution dans Ubuntu.

Mon problème est que la version parallèle prend plus de temps que la version séquentielle. Je suis en pensée c'est peut-être parce que les threads sont mappés sur le même thread du noyau ou qu'ils sont affectés à la même base. Est-il une manière que je pourrais veiller à ce que chaque fil de Java correspond à un noyau séparé?

J'ai lu d'autres posts sur ce problème, mais rien ne semble aider.

Ici c'est la fin de main() et tous les de run() pour la KnapsackThread classe (qui s'étend à Fil). Notez que la façon que j'utilise tranche supplémentaire de calculer myLowBound et myHiBound de s'assurer que chaque thread ne se chevauchent pas dans le domaine de la dynProgMatrix. Donc il n'y aura pas de conditions de course.

    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;
}
}
}

Mise à jour:

J'ai écrit une autre version du sac à dos qui utilise la force brute. Cette version a très peu de synchronisation parce que j'ai seulement besoin de mettre à jour un bestSoFar variable à la fin d'une seule exécution du thread. Par conséquent, chaque thread assez bien doit exécuter complètement en parallèle à l'exception de cette petite section critique à la fin.

J'ai couru ce rapport à l'ordre de la force brute et encore il prend plus de temps. Je ne vois pas d'autre explication que celle de mon fils sont exécutées de manière séquentielle, soit parce qu'ils sont mappées à la base même ou pour le même thread natif.

N'quelqu'un a des idée?

Bienvenue dans le monde de l'informatique parallèle! Il est très probable que vos discussions sont en fait associées à différents cœurs, et il est également probable que votre programme devrait en fait être plus rapide (bien que toujours plus lente que la version séquentielle) si ils étaient sur la même base. Où avez-vous la parallèle à dos algorithme? Il est conçu pour réduire la communication à mémoire partagée (y compris le verrouillage) autant que possible?
Il pourrait être utile que si vous postez un lien vers votre KnapsackThread code, et de dire quelque chose à propos de la quantité de fils que vous utilisez. Plus que 4 à 8 threads peut-être un problème sur un core duo,et la synchronisation des blocs peut mettre n'importe quel code 🙂
aussi ce VM utilisez-vous, le soleil sur windows et openjdk sur ubuntu, ou le soleil sur les deux?
J'ai écrit ma version à partir d'une version séquentielle par une autre personne. Il ne permet pas de verrouiller l'accès à la partagé tableau 2d, je n'ai toutefois veiller à ce que chaque thread uniquement écrit pour différents indecies du tableau 2d pour éviter des conditions de course. Je suis en utilisant un thread par core, auquel je n'par: private static KnapsackThread threads[] = new KnapsackThread[ Runtime.getRuntime().availableProcessors() ]; }
Je ne sais pas ce VM, je suis en utilisant en plus de 1.6. J'ai couru à la version de java dans le 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, en mode mixte)

OriginalL'auteur KBP | 2009-12-13