Problème thread Java et CPU

Fermé
yoann1989 - 28 juin 2011 à 17:20
 yoann1989 - 29 juin 2011 à 14:11
Bonjour,

Pour vous situer un peu le contexte de mon travail, je suis actuellement en stage dans une entreprise de biochimie.

L'objectif de mon stage est d'effectué un programme en java qui effectue des calculs sur un très grand nombre de molécules. Afin d'optimiser le temps de traitement, j'ai décidé de découper la liste de molécule en 2 et d'effectuer le traitement de chaque liste par un thread différent.


L'utilisation de ces deux threads semblent fonctionner mais les deux CPUs ne fonctionnent pas à 100% (d'où une perte de temps). Étant novice en java, et encore plus en programmation multi-threadé, j'aimerai avoir des avis, conseils et de l'aide de votre part.


PS : les CPUs oscillent entre 50 et 100%. Si vous le désirez, je peux vous fournir une impression d'écran du fonctionnement des CPUs.


Je vous remercie.

A voir également:

3 réponses

nicocorico Messages postés 799 Date d'inscription dimanche 19 juin 2011 Statut Membre Dernière intervention 3 juillet 2018 138
29 juin 2011 à 05:42
Est-ce que l'emploi du java est obligatoire, car c'est pas vraiment ce qui se fait de mieux en termes d'efficacitée ?
Et il faut savoir que l'emploi à 100% de multiprocesseurs est théorique, et en pratique ça n'arrive jamais, ne serais-ce que par le fait que le processeur master doit gérer la répartition du travail, et des conflits d'accès aux données entre les threads...

Le chêne aussi était un gland, avant d'être un chêne
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
29 juin 2011 à 06:48
Plusieurs threads s'exécutent toujours dans un même processus, ce qu'il te faudrait c'est de pouvoir répartir ta tâche sur plusieurs processus, et idéalement plusieurs processeurs.
L'idée de séparer ta liste en deux est bonne, mais si elle peut se partager en deux, elle peux peut-être l'être aussi en 4, en 8, en 16... c'est du calcul distribué !
Et là, comme le disait nicocorico, Java n'est pas forcément le plus adapté, sous Linux une utilisation de MPI en C pourrait être pas mal pour profiter des processeurs multi-coeurs.
Après le meilleur moyen de t'aider serait de nous expliquer quels genre de calculs tu fais sur ces listes de molécules, il y a peut-être des astuces qui nous viendront à l'esprit.
0
Bonjour et merci d'avoir répondu.

Je comprend bien que les 100% sont théoriques mais là, les CPUs fonctionnent entre 40 et 100%. Je trouve cette oscillation un peu large.

Afin de vous permettre d'y voir plus clair je vais vous détailler un peu ce qu'il se passe dans le programme.
Dans un premier temps on lit une fichier de type sdf (peu different d'un fichier texte) contenant l'ensemble de nos molécules (à l'aide de la librairie cdk java). Ensuite je fractionne cette base de données en plusieurs parties (autant de fois que je le souhaite mais j'ai décidé de la fragmenter autant de fois qu'il y a de processeurs). Puis dans chaque thread, une liste va être prise en charge. Chaque molécule présente dans la liste va être fragmentée afin de récupérer la masse des fragments théoriques possible (à tour de rôle à l'aide d'une boucle).
Enfin je compare les masses des fragments théoriques obtenus à des valeurs expérimentales pour voir si le modèle me permet de retrouver la molécule ayant les mêmes fragments expérimentaux et théoriques.

Le java est donc obligatoire pour les librairies permettant de manipuler les "objets molécules" et pour l'utilisation la partie de code qui fragmente car il a été prélevé sur le logiciel opensource MetFrag.
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
29 juin 2011 à 11:12
Ok, va pour Java alors, j'ai rien contre :p

Cependant, il y a je pense une mauvaise compréhension des threads lorsque tu dis : j'ai décidé de la fragmenter autant de fois qu'il y a de processeurs. Peu importe le nombre de threads que tu as, tu n'auras qu'un seul processus, donc affecté à un seul processeur.

Si je comprends bien, corrige moi si je me trompe, tous les calculs sont indépendants, si on avait par exemple un thread par molécule, c'est excessif en pratique, mais d'un point de vue théorique est-ce que ça marcherait ?

Je pense que le temps de latence vient de ta base de données, et du temps d'accès à celle-ci.
Une manière de faire pourrait être d'avoir deux threads différents, le premier (prioritaire) qui lit ta base de données et transmet les molécules au deuxième thread, et le deuxième qui fait les calculs sur les molécules qu'il a déjà reçu en attendant que la base de données réponde.
Remarque, dans ce cas ta liste serait plutôt une file, c'est le premier thread qui y ajoute les données quand il les reçoit de la base de données, et le deuxième qui les retire au moment de faire le calcul.
Éventuellement, un troisième thread, de priorité supérieure au premier pour éviter un engorgement, récupérerai les résultats à partir d'une deuxième file (remplie par le deuxième thread à la fin des calculs) pour les enregistrer dans la base de donnée.
0
Il est fort probable que ma compréhension des threads est approximative. Cependant, il me semble que lorsque que l'on créé 2 threads la JVM s'occupe de les répartir sur les deux processeurs.
Ensuite il pourrait y avoir théoriquement un thread par molécule. Car chaque thread effectue le même calcul pour chaque molécule.
En fait je suis en train d'essayer de pensée mon programme différemment. Je vais multi-threader la fragmentation de la liste de molécules. Je pense faire :
1--> Lecture du fichier et et stockage des données dans une liste de type ArrayList<IAtomContainer>.
2--> Utilisation de deux threads qui vont lire tour à tour les molécules de la liste et les fragmenter pour mettre ces fragments dans une nouvelle liste (tout cela de façon synchronisée).
3--> Effectuer de façon similaire une nouvelle fragmentation de cette liste (en fait j'ai une double fragmentation et non un simple) pour stocker le résultat dans une nouvelle liste.
4--> Enfin faire les comparaisons sur les pics finaux dans le thread principal (le main).

Cela te paraît-il plus sein en terme de programmation ?
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
29 juin 2011 à 13:40
Ton étape 1 me paraît longue à cause du temps d'accès, et ce serait dommage de perdre ce temps, c'est pour ça que je proposais de lancer les threads pour effectuer les calculs avant même que l'étape 1 ne soit terminée.
Par contre l'utilisation d'une ArrayList me parait un choix contestable, tu ne te sers pas des indices, donc une LinkedList est plus adaptée, mais si tu veux mettre en place le multi-threading il faudrait plutôt se tourner vers une ConcurrentLinkedQueue, ça permettrait aux threads de calculs d'y accéder sans soucis. Mais du coup je ferais les calculs 2 et 3 à la suite, et je ne me limiterai pas forcément à deux threads.
Au niveau de la comparaison des pics, je ne sais pas trop ce que tu veux faire, mais si le calcul est linéaire tu pourrais éventuellement faire ça au fur et à mesure que tu reçois les données, dans un dernier thread, sans attendre à chaque fois que toute la liste soit complétée pour commencer.

En gros :
Thread 1 (priorité haute)
Lire les fichiers, pour chaque élément ajouter à la file 1

Thread 2 (priorité basse) --> il y a plusieurs threads 2 exécutés en parallèle
Prendre un élément de la file 1, le calculer, ajouter le résultat à la file 2

Thread 3 (priorité moyenne)
Prendre un élément de file 2, mettre à jour les comparaisons
0
Oui, je suis d'accord. Je vais essayer de faire comme cela. Je vais également me renseigner sur les ConcurrentLinkedQueue car je ne connaissais pas ce type.
Lorsque tu parles de priorité haute, moyenne, basse cela se traduit par quelles valeurs d'indice ? 10 --> priorité haute
5 --> priorité moyenne
1 --> priorité basse
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
29 juin 2011 à 14:04
Pas forcément, je voulais juste dire haute>moyenne>basse
Que ce soit (1,2,3), (8,9,10) ou (1,5,10) ça ne change pas grand chose si ce sont les seules priorités utilisées... D'ailleurs dans ma tête je pensais plutôt à (8,9,10) ^^
0