Disons que j'ai un processeur à 4 cœurs et que je veux exécuter un processus dans le minimum de temps. Le processus est idéalement parallélisable, donc je peux en exécuter des morceaux sur un nombre infini de threads et chaque thread prend le même temps.
Étant donné que j'ai 4 cœurs, je ne m'attends à aucune accélération en exécutant plus de threads que de cœurs, car un seul cœur n'est capable d'exécuter qu'un seul thread à un moment donné. Je ne connais pas grand-chose au matériel, ce n'est donc qu'une supposition.
Existe-t-il un avantage à exécuter un processus parallélisable sur plus de threads que de cœurs? En d'autres termes, mon processus se terminera-t-il plus rapidement, plus lentement ou dans le même laps de temps si je l'exécute en utilisant 4000 threads plutôt que 4 threads?
la source
Je suis d'accord avec la réponse de @ Gonzalo. J'ai un processus qui ne fait pas d'E / S, et voici ce que j'ai trouvé:
Notez que tous les threads fonctionnent sur un tableau mais sur des plages différentes (deux threads n'accèdent pas au même index), donc les résultats peuvent différer s'ils ont travaillé sur des tableaux différents.
La machine 1.86 est un MacBook Air avec un SSD. L'autre mac est un iMac avec un disque dur normal (je pense que c'est 7200 rpm). La machine Windows a également un disque dur à 7200 tr / min.
Dans ce test, le nombre optimal était égal au nombre de cœurs dans la machine.
la source
Je sais que cette question est assez ancienne, mais les choses ont évolué depuis 2009.
Il y a deux choses à prendre en compte maintenant: le nombre de cœurs et le nombre de threads qui peuvent s'exécuter dans chaque cœur.
Avec les processeurs Intel, le nombre de threads est défini par l'hyperthreading qui n'est que de 2 (lorsqu'il est disponible). Mais Hyperthreading réduit votre temps d'exécution de deux, même si vous n'utilisez pas 2 threads! (c'est-à-dire 1 pipeline partagé entre deux processus - c'est bien quand vous avez plus de processus, pas si bien sinon. Plus de cœurs sont définitivement meilleurs!)
Sur d'autres processeurs, vous pouvez avoir 2, 4 ou même 8 threads. Donc, si vous avez 8 cœurs, chacun prenant en charge 8 threads, vous pouvez avoir 64 processus exécutés en parallèle sans changement de contexte.
"Pas de changement de contexte" n'est évidemment pas vrai si vous utilisez un système d'exploitation standard qui fera un changement de contexte pour toutes sortes d'autres choses hors de votre contrôle. Mais c'est l'idée principale. Certains systèmes d'exploitation vous permettent d'allouer des processeurs afin que seule votre application ait accès / utilisation dudit processeur!
D'après ma propre expérience, si vous avez beaucoup d'E / S, plusieurs threads sont bons. Si vous avez un travail intensif en mémoire (lecture source 1, lecture source 2, calcul rapide, écriture), avoir plus de threads n'aide pas. Encore une fois, cela dépend de la quantité de données que vous lisez / écrivez simultanément (c'est-à-dire si vous utilisez SSE 4.2 et lisez des valeurs de 256 bits, cela arrête tous les threads dans leur étape ... en d'autres termes, 1 thread est probablement beaucoup plus facile à implémenter et probablement presque aussi rapide, sinon plus rapide. Cela dépendra de votre architecture de processus et de mémoire, certains serveurs avancés gèrent des plages de mémoire distinctes pour des cœurs séparés, donc les threads séparés seront plus rapides en supposant que vos données sont correctement classées ... c'est pourquoi, sur certains architectures, 4 processus s'exécuteront plus rapidement que 1 processus avec 4 threads.)
la source
Les performances réelles dépendront du rendement volontaire de chaque thread. Par exemple, si les threads n'effectuent AUCUNE E / S et n'utilisent aucun service système (c'est-à-dire qu'ils sont liés à 100% au processeur), alors 1 thread par cœur est optimal. Si les threads font quelque chose qui nécessite une attente, vous devrez expérimenter pour déterminer le nombre optimal de threads. 4000 threads entraîneraient une surcharge de planification importante, ce qui n'est probablement pas optimal non plus.
la source
La réponse dépend de la complexité des algorithmes utilisés dans le programme. J'ai trouvé une méthode pour calculer le nombre optimal de threads en effectuant deux mesures des temps de traitement Tn et Tm pour deux nombres arbitraires de threads "n" et "m". Pour les algorithmes linéaires, le nombre optimal de threads sera N = sqrt ((m n (Tm * (n-1) - Tn * (m-1))) / (n Tn-m Tm)).
Veuillez lire mon article concernant les calculs du nombre optimal pour différents algorithmes: pavelkazenin.wordpress.com
la source
J'ai pensé ajouter une autre perspective ici. La réponse dépend du fait que la question suppose une mise à l'échelle faible ou une mise à l'échelle forte.
De Wikipédia :
Faible mise à l'échelle: comment le temps de solution varie avec le nombre de processeurs pour une taille de problème fixe par processeur.
Mise à l'échelle forte: comment le temps de solution varie avec le nombre de processeurs pour une taille de problème totale fixe.
Si la question suppose une mise à l'échelle faible, la réponse de @ Gonzalo suffit. Cependant, si la question suppose une mise à l'échelle forte, il y a quelque chose de plus à ajouter. Dans une mise à l'échelle forte, vous supposez une taille de charge de travail fixe, donc si vous augmentez le nombre de threads, la taille des données sur lesquelles chaque thread doit travailler diminue. Sur les processeurs modernes, les accès à la mémoire sont coûteux et il serait préférable de conserver la localité en conservant les données dans des caches. Par conséquent, le nombre optimal probable de threads peut être trouvé lorsque l'ensemble de données de chaque thread tient dans le cache de chaque cœur (je n'entre pas dans les détails pour savoir s'il s'agit de cache (s) L1 / L2 / L3 du système).
Cela est vrai même lorsque le nombre de threads dépasse le nombre de cœurs. Par exemple, supposons qu'il existe 8 unités arbitraires (ou AU) de travail dans le programme qui seront exécutées sur une machine à 4 cœurs.
Cas 1: exécutez avec quatre threads où chaque thread doit terminer 2AU. Chaque thread prend 10 secondes pour terminer ( avec beaucoup de ratés de cache ). Avec quatre cœurs, le temps total sera de 10 s (10 s * 4 threads / 4 cœurs).
Cas 2: exécutez avec huit threads où chaque thread doit terminer 1AU. Chaque thread ne prend que 2s (au lieu de 5s en raison de la quantité réduite de cache cache ). Avec quatre cœurs, le temps total sera de 4 s (2 s * 8 threads / 4 cœurs).
J'ai simplifié le problème et ignoré les frais généraux mentionnés dans d'autres réponses (par exemple, les changements de contexte), mais j'espère que vous comprendrez qu'il pourrait être avantageux d'avoir plus de nombre de threads que le nombre de cœurs disponibles, selon la taille des données que vous '' re traitant.
la source
4000 threads à la fois est assez élevé.
La réponse est oui et non. Si vous faites beaucoup de blocage des E / S dans chaque thread, alors oui, vous pouvez montrer des accélérations importantes faisant probablement jusqu'à 3 ou 4 threads par cœur logique.
Si vous ne faites pas beaucoup de blocages cependant, le surcoût supplémentaire avec le filetage le rendra plus lent. Utilisez donc un profileur et voyez où se trouvent les goulots d'étranglement dans chaque pièce éventuellement parallèle. Si vous effectuez des calculs lourds, alors plus d'un thread par CPU ne vous aidera pas. Si vous faites beaucoup de transfert de mémoire, cela n'aidera pas non plus. Si vous faites beaucoup d'E / S, comme pour l'accès au disque ou l'accès à Internet, alors oui, plusieurs threads aideront dans une certaine mesure, ou au moins rendront l'application plus réactive.
la source
Référence.
Je commencerais à augmenter le nombre de threads pour une application, à partir de 1, puis j'allais à quelque chose comme 100, j'exécutais trois à cinq essais pour chaque nombre de threads et je construisais vous-même un graphique de la vitesse de fonctionnement par rapport au nombre de threads. .
Vous devriez que le boîtier à quatre threads soit optimal, avec de légères augmentations de l'exécution après cela, mais peut-être pas. Il se peut que votre application soit limitée en bande passante, c'est-à-dire que l'ensemble de données que vous chargez en mémoire est énorme, vous obtenez beaucoup de ratés de cache, etc., de sorte que 2 threads sont optimaux.
Vous ne pouvez pas savoir jusqu'à ce que vous testiez.
la source
Vous trouverez combien de threads vous pouvez exécuter sur votre machine en exécutant la commande htop ou ps qui renvoie le nombre de processus sur votre machine.
Vous pouvez utiliser la page de manuel sur la commande 'ps'.
Si vous souhaitez calculer le nombre de processus de tous les utilisateurs, vous pouvez utiliser l'une de ces commandes:
ps -aux| wc -l
ps -eLf | wc -l
Calcul du nombre d'un processus utilisateur:
ps --User root | wc -l
Vous pouvez également utiliser "htop" [Référence] :
Installation sur Ubuntu ou Debian:
Installation sur Redhat ou CentOS:
Si vous souhaitez compiler htop à partir du code source, vous le trouverez ici .
la source
L'idéal est 1 fil par noyau, tant qu'aucun des fils ne se bloque.
Un cas où cela peut ne pas être vrai: il existe d'autres threads en cours d'exécution sur le noyau, auquel cas plus de threads peuvent donner à votre programme une plus grande tranche du temps d'exécution.
la source
Un exemple de nombreux threads ("pool de threads") vs un par cœur est celui de l'implémentation d'un serveur Web sous Linux ou Windows.
Étant donné que les sockets sont interrogés sous Linux, de nombreux threads peuvent augmenter la probabilité que l'un d'eux interroge le bon socket au bon moment - mais le coût de traitement global sera très élevé.
Sous Windows, le serveur sera implémenté à l'aide de ports d'achèvement d'E / S - IOCP - qui rendront l'événement d'application piloté: si une E / S se termine, le système d'exploitation lance un thread de secours pour le traiter. Une fois le traitement terminé (généralement avec une autre opération d'E / S comme dans une paire requête-réponse), le thread retourne au port IOCP (file d'attente) pour attendre la fin suivante.
Si aucune E / S n'est terminée, aucun traitement n'est à effectuer et aucun thread n'est lancé.
En effet, Microsoft ne recommande pas plus d'un thread par cœur dans les implémentations IOCP. Toute E / S peut être attachée au mécanisme IOCP. Les CIO peuvent également être affichés par l'application, si nécessaire.
la source
timeout is an upper bound on the amount of time elapsed before select() returns. If both fields of the timeval structure are zero, then select() returns immediately. (This is useful for polling.) If timeout is NULL (no timeout), select() can block indefinitely.
parlant du point de vue du calcul et de la mémoire (calcul scientifique), 4000 threads rendront l'application très lente. Une partie du problème est un surcoût très élevé de changement de contexte et très probablement une très mauvaise mémoire.
Mais cela dépend aussi de votre architecture. D'où j'ai entendu que les processeurs Niagara sont censés être capables de gérer plusieurs threads sur un seul cœur en utilisant une sorte de technique de pipelining avancée. Cependant, je n'ai aucune expérience avec ces processeurs.
la source
J'espère que cela a du sens, vérifiez l'utilisation du processeur et de la mémoire et mettez une valeur de seuil. Si la valeur seuil est franchie, ne permettez pas de créer un nouveau thread sinon autorisez ...
la source