C'est une question compliquée que vous posez. Sans en savoir plus sur la nature de vos fils, c'est difficile à dire. Quelques éléments à considérer lors du diagnostic des performances du système:
Est le processus / fil
- Lié au CPU (nécessite beaucoup de ressources CPU)
- Mémoire liée (nécessite beaucoup de ressources RAM)
- E / S liées (ressources réseau et / ou disque dur)
Ces trois ressources sont toutes finies et chacune peut limiter les performances d'un système. Vous devez voir lequel (peut-être 2 ou 3 ensemble) consomme votre situation particulière.
Vous pouvez utiliser ntop
et iostat
et vmstat
pour diagnostiquer ce qui se passe.
"Pourquoi cela arrive-t-il?" est assez facile à répondre. Imaginez que vous ayez un couloir pouvant accueillir quatre personnes côte à côte. Vous voulez déplacer toutes les ordures à une extrémité, à l'autre extrémité. Le nombre de personnes le plus efficace est de 4.
Si vous avez 1 à 3 personnes, vous manquez d'utiliser un espace de couloir. Si vous avez 5 personnes ou plus, alors au moins une de ces personnes est toujours coincée derrière une autre personne. Ajouter de plus en plus de gens obstrue simplement le couloir, cela n'accélère pas l'activité.
Donc, vous voulez avoir autant de personnes que possible sans provoquer de file d'attente. Pourquoi vous faire la queue (ou les goulots d' étranglement) dépend des questions dans la réponse de slm.
la source
4
c'est le meilleur numéro.Une recommandation courante est n + 1 threads, n étant le nombre de cœurs CPU disponibles. De cette façon, n threads peuvent faire fonctionner le CPU pendant qu'un thread attend les E / S disque. Avoir moins de threads n'utiliserait pas pleinement la ressource CPU (à un moment donné, il y aura toujours des E / S à attendre), avoir plus de threads entraînerait des conflits de threads sur la ressource CPU.
Les threads ne sont pas gratuits, mais avec des frais généraux comme des changements de contexte, et - si des données doivent être échangées entre des threads, ce qui est généralement le cas - divers mécanismes de verrouillage. Cela ne vaut le coût que si vous avez réellement plus de cœurs de processeur dédiés pour exécuter le code. Sur un processeur monocœur, un seul processus (pas de threads séparés) est généralement plus rapide que tout threading effectué. Les threads ne font pas comme par magie votre CPU aller plus vite, cela signifie juste un travail supplémentaire.
la source
Comme d' autres l' ont souligné ( slm réponse , EightBitTony réponse ) c'est une question et d' autant plus que vous ne décrivez pas compliqué ce que vous faites et thred comment ils le font.
Mais jeter définitivement plus de fils peut aggraver les choses.
Dans le domaine du calcul parallèle, il y a la loi d'Amdahl qui peut être applicable (ou pas, mais vous ne décrivez pas les détails de votre problème, donc ...) et peut donner un aperçu général de cette classe de problèmes.
Le point de la loi d'Amdahl est que dans tout programme (dans n'importe quel algorithme), il y a toujours un pourcentage qui ne peut pas être exécuté en parallèle (la partie séquentielle ) et il y a un autre pourcentage qui peut être exécuté en parallèle (la partie parallèle ) [Évidemment ces deux portions totalisent 100%].
Ces portions peuvent être exprimées en pourcentage du temps d'exécution. Par exemple, 25% du temps peut être consacré à des opérations strictement séquentielles et les 75% restants sont consacrés à des opérations pouvant être exécutées en parallèle.
(Image de Wikipedia )
La loi d'Amdahl prévoit que pour chaque portion parallèle donnée (par exemple 75%) d'un programme, vous ne pouvez accélérer l'exécution que jusqu'à présent (par exemple au plus 4 fois) même si vous utilisez de plus en plus de processeurs pour faire le travail.
En règle générale, plus vous programmez que vous ne pouvez pas transformer en exécution parallèle, moins vous pouvez obtenir en utilisant plus d'unités d'exécution (processeurs).
Étant donné que vous utilisez des threads (et non des processeurs physiques), la situation peut être encore pire que cela. N'oubliez pas que les threads peuvent être traités (en fonction de l'implémentation et du matériel disponible, par exemple CPU / Cores) partageant le même processeur / core physique (c'est une forme de multitâche, comme indiqué dans une autre réponse).
Cette prédiction théorique (sur les temps CPU) ne considère pas les autres goulots d'étranglement pratiques comme
cela peut facilement être le facteur limitant dans les applications pratiques.
la source
Le coupable ici devrait être le "CONTEXT SWITCHING". Il s'agit du processus d'enregistrement de l'état du thread actuel pour commencer à exécuter un autre thread. Si un certain nombre de threads reçoivent la même priorité, ils doivent être inversés jusqu'à ce qu'ils terminent l'exécution.
Dans votre cas, lorsqu'il y a 50 threads, beaucoup de changements de contexte ont lieu par rapport à l'exécution de 10 threads.
Cette surcharge de temps introduite à cause du changement de contexte est ce qui rend votre programme lent
la source
ps ax | wc -l
rapporte 225 processus, et il n'est en aucun cas lourdement chargé). Je suis enclin à aller avec la supposition de @ EightBitTony; L'invalidation du cache est probablement un problème plus important, car chaque fois que vous videz le cache, le processeur doit attendre des éons pour le code et les données de la RAM.Pour corriger la métaphore d'EightBitTony:
Une personne ici est un thread, et un compartiment représente la ressource d'exécution qui est le goulot d'étranglement. L'ajout de fils de discussion n'aide pas s'ils ne peuvent rien faire. De plus, nous devons souligner que le passage d'un seau d'une personne à une autre est généralement plus lent qu'une seule personne portant simplement le seau à la même distance. C'est-à-dire que deux threads à tour de rôle sur un noyau accomplissent généralement moins de travail qu'un seul thread s'exécutant deux fois plus longtemps: cela est dû au travail supplémentaire effectué pour basculer entre les deux threads.
Que la ressource d'exécution limitée (bucket) soit un processeur, un noyau ou un pipeline d'instructions hyper-threaded pour vos besoins dépend de la partie de l'architecture qui constitue votre facteur limitant. Notez également que nous supposons que les threads sont entièrement indépendants. Ce n'est le cas que s'ils ne partagent aucune donnée (et évitent toute collision avec le cache).
Comme deux personnes l'ont suggéré, pour les E / S, la ressource limitante pourrait être le nombre d'opérations d'E / S pouvant être mises en file d'attente: cela pourrait dépendre de toute une série de facteurs matériels et du noyau, mais pourrait facilement être beaucoup plus important que le nombre de noyaux. Ici, le changement de contexte qui est si coûteux par rapport au code lié à l'exécution, est assez bon marché par rapport au code lié aux E / S. Malheureusement, je pense que la métaphore deviendra complètement hors de contrôle si j'essaie de justifier cela avec des seaux.
Notez que le optimale comportement avec le code lié d' E / S est typiquement encore d'avoir au plus un fil par pipeline / core / CPU. Cependant, vous devez écrire du code d'E / S asynchrone ou synchrone / non bloquant, et l'amélioration relativement faible des performances ne justifiera pas toujours la complexité supplémentaire.
PS. Mon problème avec la métaphore du couloir d'origine est qu'elle suggère fortement que vous devriez pouvoir avoir 4 files d'attente de personnes, avec 2 files d'attente transportant des déchets et 2 revenant pour en collecter plus. Ensuite, vous pouvez faire chaque file d'attente presque aussi longtemps que le couloir, et l'ajout de personnes a accéléré l'algorithme (vous avez essentiellement transformé tout le couloir en tapis roulant).
En fait, ce scénario est très similaire à la description standard de la relation entre la latence et la taille de la fenêtre dans les réseaux TCP, c'est pourquoi il m'a sauté aux yeux.
la source
C'est assez simple et simple à comprendre. En ayant plus de threads que ce que votre CPU prend en charge, vous sérialisez et non parallélisez. Plus vous avez de threads, plus votre système sera lent. Vos résultats sont en fait une preuve de ce phénomène.
la source