meilleure utilisation de la Parallèle.ForEach / Multithreading
J'ai besoin de recueillir des données à partir d'un site web.
J'ai plus de 1000 liens que j'ai besoin d'accéder à, et auparavant, j'étais en divisant les liens 10 par thread, et commencerait 100 fils de chaque tirant 10. Après quelques cas de test, 100 fils a été la meilleure valeur pour minimiser le temps qu'il extrait le contenu de tous les liens.
J'ai réalisé que .NET 4.0 offert un meilleur support pour le multi-threading hors de la boîte, mais cela est fait en fonction du nombre de coeurs que vous avez, ce qui dans mon cas ne fraient pas assez de threads. Je suppose que ce que je pose est: quelle est la meilleure façon d'optimiser les 1000 lien tirant. Dois-je utiliser .ForEach
et de laisser le Parallel
le contrôle de l'extension de la quantité de threads qui se donné lieu, ou trouver un moyen de dire le nombre de threads de début et de répartir le travail?
Je n'ai pas travaillé avec Parallel
avant, donc peut-être que mon approche peut-être tort.
Fortement d'e / s réseau des tâches limitées, qui n'est pas nécessairement vrai. Aussi longtemps que le pool de threads n'est pas épuisé, permettant à plusieurs demandes simultanées est probablement une bonne chose. Si vous avez 100 threads et un temps de réponse de 1 seconde, c'est seulement à plus de 100 changements de contexte par seconde sur un seul système de base, ou 25 sur un quad core. Bien sûr, ce sont toutes des suppositions numéros, mais on dirait que l'OP a essayé une variété de paramètres et se sont installés sur ces être le mieux pour son cas d'utilisation et le matériel.
C'est pourquoi je dis "probablement". De toute façon, j'allais encore avec un async solution avant de tourner jusqu'à 100 threads.
Async serait une très bonne alternative. Peut-être ajouter une autre réponse?
Ouais, mais si vous n'avez pas de soins sur la perte de 100 MO de mémoire et vous ne pouvez pas utiliser le C# 5.0, puis la création de 100 threads est beaucoup mieux que de le faire de manière asynchrone.
OriginalL'auteur Zoinky | 2013-02-08
Vous devez vous connecter pour publier un commentaire.
Quelque chose de la peine de vérifier est le TPL de Flux de données de la bibliothèque.
Flux de données sur MSDN.
Voir L'imbrication attendent en Parallèle.ForEach
Aussi, la procédure pas à pas La création d'un Flux de données à Pipeline spécifiquement met en place et des processus multiples de la page web de téléchargements. TPL Dataflow vraiment été conçu pour ce scénario.
Il y a aussi manières d'écrire un
ForEachAsync
, mais l'OMI des Flux de données, est un ajustement parfait pour ce problème. +1.OriginalL'auteur Cameron MacFarland
En général,
Parallel.ForEach()
est assez bonne à l'optimisation du nombre de threads. Il représente le nombre de cœurs dans le système, mais prend également en compte ce que les fils sont en train de faire (CPU, IO lié, combien de temps la méthode fonctionne, etc.).Vous pouvez contrôler le degré maximal de parallélisme, mais il n'y a pas de mécanisme de forcer plus de threads à utiliser.
Assurez-vous que vos repères sont correctes et peuvent être comparés de façon équitable (p. ex. sites web de même, prévoir une période d'échauffement avant de commencer à mesurer, et de faire beaucoup de pistes depuis le temps de réponse de la variance peut être très élevé en raclant les sites web). Si, après une évaluation précise de votre propre filetage code est encore plus rapide, vous pouvez en conclure que vous avez optimisé pour votre cas particulier, mieux que .NET et le bâton avec votre propre code.
OriginalL'auteur Eric J.
vous pouvez utiliser MaxDegreeOfParallelism propriété en Parallèle.ForEach pour contrôler le nombre de threads qui seront pondus.
Voici l'extrait de code -
MaxDegreesOfParallelism
n'est pas une garantie, seulement une limite supérieure. Et si vous ne définissez pas de valeur ici, la valeur par défaut est basé sur le nombre de cœurs, la charge du système, etc.OriginalL'auteur whihathac
Difficile à dire sans regarder ton code et la façon dont la collecte est défini, j'ai trouvé que
Parallel.Invoke
est la plus flexible. essayez msdn? ... on dirait que vous cherchez à utiliserParallel.For Method (Int32, Int32, Action<Int32, ParallelLoopState>)
OriginalL'auteur Chris Noffke