2011-10-12 1 views
2

J'ai un programme qui trie les gros fichiers en les divisant en morceaux, en triant les morceaux et en les fusionnant dans le fichier trié. L'application exécute un thread pour charger/enregistrer des données depuis/vers un fichier - un seul thread effectue les opérations d'E/S. De plus, deux autres threads reçoivent des données de bloc, les trient et envoient ensuite des données triées vers le thread qui effectue les E/S. Donc, en général, il y a 4 threads en cours d'exécution - thread principal, thread qui charge/enregistre des données et deux threads qui trient les données.Utilisation du processeur multi-cœur par l'application Java

Je pensais que pendant l'exécution, je verrai 1 thread de sommeil (principal) qui ne prend pas de temps de processeur et 3 threads actifs qui utilisent chacun 1 CPU. Lorsque j'exécute ce programme sur une machine à double processeur à 6 coeurs avec hyper threading (24 CPU), je vois que TOUTES les 24 CPU sont chargées à 100%! Initialement, je pensais que l'algorithme de tri est mutithreaded, mais après avoir regardé dans les sources java j'ai trouvé que ce n'est pas le cas.

J'utilise simplement Collections.sort (LinkedList) pour trier les données ...

voici quelques détails:

 
# java -version 
java version "1.6.0_26" 
Java(TM) SE Runtime Environment (build 1.6.0_26-b03) 
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode) 

# uname -a 
Linux 2.6.32-28-server #55-Ubuntu SMP Mon Jan 10 23:57:16 UTC 2011 x86_64 GNU/Linux 

j'utilisais nmon pour surveiller le chargement du processeur.

Je vous serais reconnaissant toute explication de ce cas et tout conseil sur la façon de contrôler le chargement du CPU i cette tâche particulière ne laisse pas le temps CPU pour d'autres applications

[UPDATE] je jvisualvm compter les discussions - il montre seulement les fils que je connais. J'ai aussi fait un programme de test simple (voir ci-dessous) qui fonctionne un seul thread principal et obtenu exactement les mêmes résultats - les 24 processeurs sont occupés presque 100% lors de l'exécution de code

public class Test { 

    public void run(){ 
     Random r = new Random(); 
     int len = r.nextInt(10) + 5000000; 
     LinkedList<String> list = new LinkedList<String>(); 
     for (int i=0; i<len; i++){ 
       list.add(new String("test" + r.nextInt(50000000))); 
     } 
     System.out.println("Inserted " + list.size() + " items"); 
     list.clear(); 
    } 

    public static void main(String[] argv){ 
     Test t = new Test(); 
     t.run(); 
     System.out.println("Done"); 
    } 
} 

[UPDATE]
Voici la capture d'écran i fait lors de l'exécution du programme ci-dessus (utilisé nmon): http://imageshack.us/photo/my-images/716/cpuload.png/

+1

Nous avons probablement besoin de voir votre code pour comprendre cela. Je suppose que vous utilisez plus de threads que vous ne le pensez. –

+0

J'ai utilisé jvisualvm pour compter les threads - il ne montre que les threads que je connais. Aussi j'ai fait un programme de test simple qui ne fonctionne que d'un thread principal et obtenu exactement les mêmes résultats. S'il vous plaît voir ma mise à jour en question. –

+0

4 threads ne peuvent pas utiliser 100% d'utilisation de 6 cœurs. Soit vous avez plus de fils ou vos mesures sont erronées. –

Répondre

1

Je dirais, que ce soit plutôt une nmon qu'une question de java et de le résoudre, je prendrais un coup d'oeil à la commande top qui fournit des informations sur l'utilisation de cpu par processus. Je prédis le résultat suivant: Vous verrez un thread Java utilisant près de 100% cpu-time (ce qui est correct, car le pourcentage de processus en haut est relatif à un noyau (virtuel)), peut-être un deuxième et un troisième thread java avec beaucoup moins cpu-usage (les threads d'E/S). Selon le choix du gc, vous pouvez même voir un ou plusieurs gc-Threads, mais beaucoup moins de 20.

HotSpot ne pourra cependant pas (et même pas à ma connaissance) paralléliser une tâche séquentielle à elle seule.

+0

J'ai inspecté l'application avec "top -H" et il y avait beaucoup de threads appartenant à Java. Alors j'inspectée l'application avec « jstack » lors de l'exécution et y trouvèrent un bon nombre de threads gc: « GC fil de tâche # 0 » .... « fil tâche GC# 14 » Donc, je crois que le chargement montré par nmon a été généré par des threads GC. Je vais lire plus sur la façon de contrôler GC. @Jonathan merci de revenir avec l'idée de GC, vous avez mon vote –

+0

J'ai utilisé -XX: ParallelGCThreads pour contrôler le nombre de threads et obtenu exactement les résultats attendus dans nmon - 4 threads d'application utilisés 4 cœurs. @Johnatan merci encore! –

Questions connexes