14 votes

Java Performance Processes vs Threads

Je suis en train de mettre en œuvre un pool de travailleurs en Java.

C'est essentiellement un ensemble complet d'objets qui vont récupérer des morceaux de données, traiter les données, puis stocker le résultat. En raison de la latence des entrées/sorties, il y aura significativement plus de travailleurs que de cœurs de processeur.

Le serveur est dédié à cette tâche et je veux tirer le meilleur parti des performances du matériel (mais non, je ne veux pas l'implémenter en C++).

La mise en œuvre la plus simple consisterait à avoir un seul processus Java qui crée et surveille un certain nombre de threads travailleurs. Une alternative serait d'exécuter un processus Java pour chaque travailleur.

En supposant à titre d'exemple un serveur Linux quadcore, lequel de ces solutions anticiperiez-vous être plus performant et pourquoi ?

Vous pouvez supposer que les travailleurs n'ont jamais besoin de communiquer les uns avec les autres.

18voto

Ed Staub Points 7386

Un processus, plusieurs threads - pour quelques raisons.

Lors de la commutation de contexte entre les tâches, il est moins coûteux sur certains processeurs de passer d'un thread à l'autre que d'un processus à un autre. Cela est particulièrement important dans ce genre de cas limité par les entrées/sorties, avec plus de travailleurs que de cœurs. Plus vous travaillez entre les blocages d'E/S, moins cela est important. Un bon tamponnement compensera les threads ou les processus, cependant.

Lors de la commutation entre les threads dans le même JVM, au moins certaines implémentations Linux (x86, en particulier) n'ont pas besoin de vider le cache. Voir le blog de Tsuna. La pollution du cache entre les threads sera minimisée, car ils peuvent partager le cache du programme, effectuent la même tâche et partagent la même copie du code. Nous parlons d'économies de l'ordre de centaines de nanosecondes à plusieurs microsecondes par commutation. Si ce n'est pas important pour vous, alors continuez la lecture...

En fonction de la conception, le chemin des données E/S peut être plus court pour un processus.

Le temps de démarrage et de montée en température pour un thread est généralement beaucoup plus court. Le système d'exploitation n'a pas besoin de démarrer un processus, Java n'a pas à démarrer un autre JVM, le chargement des classes est effectué une seule fois, la compilation JIT est effectuée une seule fois et les optimisations HotSpot ne sont faites qu'une fois, et plus tôt.

18voto

Shivan Dragon Points 8626

Eh bien, en général, lorsque l'on discute du multi-processing (/w un thread par processus) par rapport au multi-threading dans le même processus, alors que le surcoût théorique est plus important dans le premier cas que dans le second (et donc le multi-processing est théoriquement plus lent que le multi-threading), en réalité, sur la plupart des OS modernes, ce n'est pas un si gros problème. Cependant, lorsque l'on en parle dans le contexte de Java, démarrer un nouveau processus est beaucoup plus coûteux que de démarrer un nouveau thread. Démarrer un nouveau processus signifie démarrer une nouvelle instance de la JVM qui est très coûteuse, surtout en termes de mémoire. Je recommande que vous lanciez plusieurs threads dans la même JVM.

De plus, si vous dites que la communication entre threads n'est pas un problème, vous pouvez utiliser le Executor Service de Java pour obtenir un pool de threads fixe de taille 2x(le nombre de CPU disponibles). Le nombre de CPU disponibles peut être détecté automatiquement au moment de l'exécution via la classe Runtime de Java. De cette façon, vous obtenez un multithreading simple et rapide sans avoir à écrire de code supplémentaire.

1voto

A User Points 49

En réalité, si vous réalisez cela avec des tâches à grande échelle en utilisant plusieurs processus JVM, c'est beaucoup plus rapide qu'avec un seul JVM avec plusieurs threads. Au moins, nous n'avons jamais eu un JVM fonctionnant aussi rapidement que plusieurs JVM.

Nous effectuons certains calculs où chaque tâche utilise environ 2 à 3 Go de RAM et effectue un traitement intensif des nombres. Si nous lançons 30 JVM et exécutons 30 tâches, elles fonctionnent environ 15 à 20% mieux que si nous lancions 30 threads dans un seul JVM. Nous avons essayé d'optimiser le GC et les différentes sections de mémoire et n'avons jamais réussi à rattraper la première variante.

Nous avons fait cela sur diverses machines avec 14 tâches sur un serveur 16 cœurs, 34 tâches sur un serveur 36 cœurs, etc. Le multithreading en java a toujours fonctionné moins bien que plusieurs processus JVM.

Cela peut ne faire aucune différence sur des tâches simples, mais sur des calculs lourds, il semble que les performances des JVM soient mauvaises avec les threads.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X