Ce n'MaxDegreeOfParallelism faire?
Je suis en utilisant en Parallèle.ForEach et je suis en train de faire une base de données mises à jour, maintenant, sans réglage de MaxDegreeOfParallelism , un processeur dual core de la machine des résultats dans sql client, les délais d'attente, où d'autre processeur quad core de la machine en quelque sorte, n'a pas de délai d'attente.
Maintenant, je n'ai aucun contrôle sur ce genre de cœurs de processeur sont disponibles à l'endroit où mon code fonctionne, mais s'il y a des paramètres que je peux changer avec MaxDegreeOfParallelism qui sera probablement moins d'opérations en même temps et pas de résultat dans les délais d'attente?
Je peux augmenter les délais d'attente, mais ce n'est pas une bonne solution, si sur le bas du CPU j'ai peut traiter des opérations, simultanément, qu'il va mettre moins de charge sur le cpu.
Ok, j'ai tout lu d'autres posts et MSDN trop, mais la mise en MaxDegreeOfParallelism à une valeur inférieure faire mon quad core machines souffrir?
Par exemple, est-il de toute façon à faire quelque chose comme, si le CPU a deux cœurs, puis utiliser des 20, si le PROCESSEUR dispose de quatre cœurs de 40?
Vous devez vous connecter pour publier un commentaire.
La réponse est que c'est la limite supérieure pour l'ensemble de la marche en parallèle, quel que soit le nombre de cœurs.
Donc, même si vous n'utilisez pas le CPU parce que vous êtes en attente sur IO, ou un verrou, pas de supplément de tâches s'exécutent en parallèle, seul le maximum que vous spécifier.
Pour le savoir, j'ai écrit ce morceau de code de test. Il est artificiel de verrouillage afin de stimuler le TPL d'utiliser plusieurs threads. La même chose se produira lorsque votre code est en attente d'ar ou de la base de données.
Si je ne spécifiez pas MaxDegreeOfParallelism, la journalisation de la console indique que jusqu'à environ 8 tâches sont en cours d'exécution en même temps. Comme ceci:
Il commence à un niveau bas, augmente au fil du temps et à la fin, il essaie de 8 en même temps.
Si je me limite à un certain arbitraire de la valeur (disons 2), j'ai
Oh, et c'est sur un quadcore de la machine.
Vous pouvez faire pour rendre le parallélisme dépend du nombre de cœurs de PROCESSEUR:
Cependant, de nouveaux CPU ont tendance à utiliser la technologie hyper-threading pour simuler supplémentaire cœurs. Donc, si vous avez un processeur quad-core, puis
Environment.ProcessorCount
sera probablement en rapport de ce que les 8 coeurs. J'ai trouvé que si vous définissez le parallélisme de compte pour la simulation de carottes puis il ralentit vers le bas les autres threads comme les threads UI.Si bien que l'opération va se terminer un peu plus rapide, une INTERFACE utilisateur de l'application peut éprouver un retard important au cours de cette période. La division de la `Environnement.ProcessorCount' par 2 semble atteindre les mêmes vitesses de traitement tout en gardant le CPU disponibles pour l'INTERFACE utilisateur de threads.
Il semble que le code que vous êtes en cours d'exécution en parallèle est le blocage, ce qui signifie que, à moins que vous pouvez trouver et corriger le problème à l'origine de cela, vous ne devriez pas paralléliser à tous.
Autre chose à considérer, surtout pour les personnes à trouver cela bien des années plus tard, est selon votre situation, il est généralement préférable de recueillir toutes les données dans un DataTable et ensuite utiliser SqlBulkCopy à la fin de chaque tâche majeure.
Par exemple, j'ai un processus que j'ai fait qui s'exécute par des millions de fichiers et j'ai couru dans les mêmes erreurs lors de chaque fichier de transaction de la base de données de requête pour insérer l'enregistrement. J'ai plutôt avancé pour stocker le tout dans un DataTable dans la mémoire pour chaque action je itérer, de dumping de la DataTable dans mon SQL Server et de compensation entre chaque action. Le bulk insert prend une fraction de seconde et a l'avantage de ne pas ouvrir des milliers de connexions à la fois.
EDIT:
Voici un rapide & sale travail exemple
Le SQLBulkCopy méthode:
...et pour les déverser dans la datatable:
...et voici le contexte, la boucle de la pièce elle-même:
Comme indiqué ci-dessus, c'est rapide & sale, mais fonctionne très bien.
Pour des problèmes de mémoire, j'ai couru dans une fois que je suis à environ 2 000 000 d'enregistrements, j'ai dû créer un deuxième DataTable et alterner entre les 2, le dumping des dossiers à SQL server entre l'alternance. Donc, mes connexions SQL se composent de 1 tous les 100 000 entrées.
J'ai réussi que comme ceci:
Où "datatableRecordCountThreshhold = 100000"
il détermine le nombre de threads de s'exécuter en parallèle...