Le nombre Optimal de threads par noyau
Disons que j'ai un PROCESSEUR 4 cœurs, et je veux lancer un processus dans le minimum de temps. Le processus est idéalement parallélisables, donc, je peux utiliser des morceaux de celui-ci sur un nombre infini de fils et chaque thread prend la même quantité de temps.
Depuis que j'ai 4 coeurs, je n'ai pas s'attendre à une accélération en cours d'exécution de plus de threads que de cœurs, car un seul core est seulement capable d'exécuter un seul thread à un moment donné. Je ne sais pas beaucoup sur le matériel, si ce n'est qu'une supposition.
Est-il un avantage à utiliser une parallélisables processus sur plus de threads que de cœurs? En d'autres termes, mon processus de finition plus rapide, plus lent, ou dans environ la même quantité de temps si je l'exécute à l'aide de 4000 threads plutôt que 4 threads?
Vous devez vous connecter pour publier un commentaire.
Si votre fils de ne pas faire d'e/S, synchronisation, etc., et il n'y a rien d'autre en cours d'exécution, 1 thread par core permettra d'obtenir le meilleur rendement. Cependant que très probablement pas le cas. L'ajout de plus de threads permet habituellement, mais après un certain point, ils provoquent une dégradation des performances.
N'y a pas longtemps, je faisais des tests de performance sur un 2 quad-core de la machine de l'exécution d'une ASP.NET application sur Mono sous un assez décent de charge. Nous avons joué avec le minimum et le nombre maximum de threads et à la fin, nous avons constaté que pour une application particulière dans cette configuration le meilleur débit se situe entre 36 et 40 threads. Rien à l'extérieur de ces limites effectué pire. Leçon apprise? Si j'étais vous, je voudrais tester avec différents nombre de threads jusqu'à ce que vous trouver le bon numéro pour votre application.
Une chose est sûre: 4k fils va prendre plus de temps. C'est beaucoup de changements de contexte.
Je suis d'accord avec @Gonzalo de réponse. J'ai un processus qui ne fait pas de I/O, et voici ce que j'ai trouvé:
Noter que tous les threads de travail sur un tableau, mais les différentes gammes (les deux fils n'ont pas accès au même indice), de sorte que les résultats peuvent différer si ils ont travaillé sur les différents tableaux.
La 1.86 machine est un macbook air avec un SSD. Les autres mac est un iMac avec un HDD normal (je pense que c'est un 7200 tr /min). Les fenêtres de la machine dispose également d'un 7200 tr /min disque dur.
Dans ce test, le nombre optimal est égal au nombre de cœurs de la machine.
Je sais que cette question est un peu vieux, mais les choses ont évolué depuis 2009.
Il y a deux choses à prendre en compte: le nombre de cœurs, et le nombre de threads qui peuvent s'exécuter à l'intérieur de chaque cœur.
Avec les processeurs Intel, le nombre de threads est définie par la fonction Hyperthreading, qui est à seulement 2 (lorsque disponible). Mais l'Hyperthreading réduit votre temps d'exécution par deux, même lorsque vous n'utilisez pas 2 fils! (c'est à dire 1 pipeline partagé entre deux processus -- ce est bon quand vous avez plus de processus, mais pas autrement. Plus de cœurs sont définitivement mieux!)
Sur d'autres processeurs, vous pouvez avoir 2, 4 ou même 8 threads. Donc, si vous avez 8 cœurs de chacun de soutien 8 threads, vous pourriez avoir 64 processus s'exécutant en parallèle, sans changement de contexte.
"Pas de changement de contexte" n'est évidemment pas vrai, si vous exécutez un système d'exploitation standard qui va faire le 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 de sorte que seul votre application a accès ou à l'utilisation dudit processeur!
À partir de ma propre expérience, si vous avez beaucoup d'I/O, plusieurs threads est bon. Si vous avez de très lourds de la mémoire de travail intensif (lire la source 1, lecture de la source 2, rapide calcul, écriture) puis avoir plus de threads n'aide pas. Encore une fois, cela dépend de la quantité de données en lecture/écriture simultanément (si vous utilisez de l'ESS 4.2 et lire 256 valeurs de bits, qui s'arrête tous les threads dans leur démarche... en d'autres mots, 1 thread est probablement beaucoup plus facile à mettre en œuvre et sans doute à peu près aussi rapide sinon plus rapide. Cela dépendra de votre process & architecture de la mémoire, certains serveurs d'avancées de gérer des plages de mémoire pour séparer les noyaux afin de séparer les fils sera plus rapide en supposant que vos données sont correctement classés,... c'est pourquoi, sur certaines architectures, 4 processus sera exécuté plus rapidement que 1 processus avec 4 fils.)
Le rendement réel dépendra de la façon dont beaucoup volontaire de rendement de chaque thread va faire. Par exemple, si les fils ne sont PAS d'I/O à tous et utilisez pas de système de services (c'est à dire qu'ils sont à 100% de cpu-bound) puis 1 thread par core qui est optimal. Si les fils ne sont tout ce qu'il faut attendre, alors vous aurez à faire des essais pour déterminer le nombre optimal de threads. 4000 fils engager d'importantes surcharge de planification, de sorte que c'est probablement pas optimale non plus.
La réponse dépend de la complexité des algorithmes utilisés dans le programme. Je suis venu avec une méthode pour calculer le nombre optimal de threads en utilisant les deux mesures de temps de traitement des Tn et Tm pour les deux arbitraire nombre de threads ‘n’ et ‘m’. Pour les algorithmes linéaires, le nombre optimal de threads sera N = sqrt ( (mn(Tm*(n-1) Tn*(m-1)))/(nTn-mTm) ) .
Veuillez lire mon article concernant les calculs du nombre optimal pour les différents algorithmes: pavelkazenin.wordpress.com
4000 threads en même temps est assez élevé.
La réponse est oui et non. Si vous faites beaucoup de blocage I/O dans chaque thread, alors oui, vous pouvez afficher des accélérations significatives faire jusqu'à probablement 3 ou 4 threads par logique de base.
Si vous ne faites pas beaucoup de bloquer les choses mais dans ce cas, les frais généraux supplémentaires avec filetage, va juste le rendre plus lent. Il faut donc utiliser un générateur de profils et de voir où les goulets d'étranglement dans chacun parallèle pièce. Si vous faites de lourds calculs, plus de 1 thread par CPU ne va pas aider. Si vous faites beaucoup de transfert de mémoire, il ne va pas aider non plus. Si vous faites beaucoup d'I/O, mais comme pour les accès disque ou d'accès à internet, alors oui plusieurs threads vont aider jusqu'à un certain point, ou au moins de rendre l'application plus réactive.
Je pensais ajouter un autre point de vue ici. La réponse dépend de la question est en supposant que la faiblesse de la mise à l'échelle ou une forte mise à l'échelle.
De Wikipédia:
La faiblesse de la mise à l'échelle: la façon dont la solution varie avec le nombre de processeurs pour une correction d'un problème de taille par processeur.
Forte de mise à l'échelle: la façon dont la solution varie avec le nombre de processeurs pour un total fixe problème de taille.
Si la question est en supposant que la faiblesse de la mise à l'échelle, puis @Gonzalo réponse suffit. Toutefois, si la question est en supposant une forte mise à l'échelle, il y a quelque chose de plus à ajouter. Forte de mise à l'échelle vous êtes en supposant un fixe de la charge de travail de taille donc, si vous augmenter le nombre de threads, la taille des données que chaque thread a besoin de travailler sur des baisses. Sur les Processeurs modernes les accès à la mémoire sont chers et serait préférable de maintenir la localité en conservant les données dans les caches. Il est donc probable qu'un nombre optimal de threads peut être trouvé lorsque le jeu de données de chaque thread s'adapte dans chaque cœur du cache (je ne vais pas rentrer dans les détails de la question de savoir s'il en L1/L2/L3 cache(s) du système).
Cela est vrai même lorsque le nombre de threads dépasse le nombre de cœurs. Par exemple supposer il y a 8 arbitraire de l'unité (ou AU) de travail dans le programme, qui sera exécuté sur un 4 core de la machine.
Cas 1: courir avec quatre threads où chaque thread doit remplir 2AU. Chaque thread prend 10s pour terminer (avec beaucoup de défauts de cache). Avec quatre coeurs, le montant total de temps sera 10s (10s * 4 threads /4 cœurs).
Cas 2: courir avec huit threads où chaque thread doit remplir 1AU. Chaque thread ne prend que 2 (au lieu de 5 à cause de la la réduction de la quantité de cache). Avec huit cœurs le temps total sera 4s (2s * 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 (p. ex., changements de contexte), mais j'espère que vous obtenez le point qu'il pourrait être avantageux de disposer d'un plus grand nombre de threads que le nombre de cœurs en fonction de la taille des données que vous avez affaire.
De référence.
J'aimerais commencer à augmenter le nombre de threads d'une application, en commençant à 1, puis aller pour quelque chose comme 100, exécuter trois à cinq essais pour chaque nombre de threads, et vous construire un graphique de la vitesse de fonctionnement est fonction du nombre de threads.
Vous devriez que les quatre thread cas est optimal, avec des légères hausses dans l'exécution une fois, mais peut-être pas. Il se peut que votre application est la largeur de bande limitée, c'est à dire, l'ensemble de données que vous êtes en train de charger dans la mémoire est énorme, vous obtenez beaucoup de défauts de cache, etc, de sorte que 2 threads sont optimales.
Vous ne pouvez pas savoir jusqu'à ce que vous testez.
Vous trouverez le nombre de threads que vous pouvez exécuter sur votre machine en cours d'exécution htop ou de la commande ps, qui retourne le numéro de processus sur votre ordinateur.
Vous pouvez utiliser la page de man à propos de 'ps' de la commande.
Si vous voulez calculer le nombre de tous les utilisateurs, vous pouvez utiliser l'une de ces commandes:
ps -aux| wc -l
ps -eLf | wc -l
Calcul du nombre de processus utilisateur:
ps --User root | wc -l
Aussi, vous pouvez utiliser "htop" [Référence]:
Installation sur Ubuntu ou Debian:
L'installation de Redhat ou CentOS:
Si vous voulez compiler htop à partir du code source, vous trouverez qu'il ici.
L'idéal est de 1 thread par cœur, tant qu'aucun des fils ne bloque.
Un cas où ce ne peut pas être vrai: il y a d'autres threads en cours d'exécution sur la base, dans ce cas, plus de threads peuvent donner à votre programme une part plus importante du temps d'exécution.
Un exemple de beaucoup de fils ("pool de threads") vs un par cœur, c'est que de la mise en œuvre d'un serveur web sous Linux ou Windows.
Depuis sockets sont interrogés dans Linux beaucoup de threads peuvent augmenter la probabilité de l'un des bureaux de la prise droite au bon moment - mais dans l'ensemble, le coût sera très élevé.
Dans Windows, le serveur sera mis en œuvre à l'aide de I/O Ports de fin d' - IOCPs - qui permettra à l'application event driven: si une e/S est terminée le système d'exploitation lance un thread pour traiter. Lorsque le traitement est terminé (généralement avec une autre opération d'e/S comme dans une requête-réponse paire) le fil revient à l'IOCP port (file d'attente) pour attendre le prochain achèvement.
Si aucune e/S est terminée il n'y a pas de traitement à faire et pas de thread est lancé.
En effet, Microsoft recommande de ne pas plus d'un thread par core dans IOCP implémentations. I/O peut être joint à l'IOCP mécanisme. IOCs peuvent également être affichées par l'application, si nécessaire.
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 de mémoire et de calcul lié point de vue (calcul scientifique) 4000 fils fera de l'exécution de l'application vraiment très lent. Une partie du problème est d'un très haut dans le ciel de la commutation de contexte et les plus susceptibles de mauvaise localité de mémoire.
Mais cela dépend aussi de votre architecture. D'où j'ai entendu Niagara processeurs sont censés être en mesure de gérer plusieurs threads sur un seul core à l'aide de une sorte de pointe pipelining technique. Cependant, je n'ai aucune expérience avec ces processeurs.
Espérons que cela a du sens, Vérifier le CPU et l'utilisation de la Mémoire et de mettre la valeur de seuil. Si la valeur de seuil est franchi,ne permettent pas de créer un nouveau thread d'autre permettent...