J'ai été chargé de prendre une simulation de Monte Carlo de Monte Carlo de Monte Carlo Thread Carlo Strong> et Optimiser Strong> IT. Ceci est une application C # Console, Aucun accès DB Il charge des données une fois à partir d'un fichier CSV et l'écrit à la fin, il est donc L'algorithme de base J'aimerais que les développeurs pèsent sur: p> Certains L'application actuelle prend 2 heures pour 500 000 itérations, l'entreprise a besoin de cela pour atteindre 3 000 000 itérations et être appelée fois par jour par jour, alors besoin d'une optimisation lourde. P> particulièrement d'entendre des personnes fortes> qui ont utilisé Ceci doit être réalisé assez rapidement si merci p> Mise à jour Strong> P> Je viens d'essayer le parallèle. Pour la mise en œuvre, mais il s'agit de des résultats étranges.
Fileté unique: p> à: p> intérieur simulant Il y a beaucoup d'appels à rnd.nexiforme (), Peut-être aussi des problèmes avec la liste addrange appeler n'étant pas le fil de sécurité? Je vois ce P> System.Threading.Collections.BlockingCollection peut être utile, mais il n'a qu'une méthode d'addition, aucun addrange, je devrais donc regarder là-bas des résultats et ajouter un fil de sécurité. Tout aperçu de quelqu'un qui a utilisé parallèle.Pour très apprécié. J'ai passé temporairement à la
3 Réponses :
Tout d'abord, vous devez comprendre pourquoi vous pensez que l'utilisation d'utiliser plusieurs threads est une optimisation - quand elle est, en fait, pas. L'utilisation de plusieurs threads rendra votre charge de travail complète plus rapidement uniquement em> si vous avez plusieurs processeurs, puis au plus rapidement que vous avez des processeurs disponibles (ceci s'appelle le Speed-up em >). Le travail n'est pas "optimisé" dans le sens traditionnel du mot (c'est-à-dire que la quantité de travail n'est pas réduite - en fait, avec multithreading, la quantité totale de travail augmente généralement en raison de la surcharge de filetage). P>
Donc, dans la conception de votre application, vous devez trouver des morceaux de travail pouvant être effectués de manière parallèle ou se chevauchant. Il peut être possible de générer des nombres aléatoires en parallèle (en utilisant plusieurs RNG exécutés sur différents processeurs), mais cela modifierait également les résultats, car vous obtenez différents nombres aléatoires. Une autre option a une génération de nombres aléatoires sur un processeur et tout le reste sur différents processeurs. Cela peut vous donner une vitesse maximale de 3, car la RNG fonctionnera toujours séquentiellement et prendra toujours 30% de la charge. P>
Donc, si vous optez pour cette parallélisation, vous vous retrouvez avec 3 threads: le fil 1 exécute le rng, le fil 2 produit une distribution normale et le fil 3 fait le reste de la simulation. P>
Pour cette architecture, un Architecture producteur-consommateur a > est le plus approprié. Chaque thread va lire son entrée à partir d'une file d'attente et produira sa sortie dans une autre file d'attente. Chaque file d'attente doit être bloquée, de sorte que si le fil RNG tombe derrière, le fil de normalisation bloquera automatiquement jusqu'à ce que de nouveaux nombres aléatoires soient disponibles. Pour une efficacité, je transmettrais les nombres aléatoires dans la matrice de, disons, 100 (ou plus grand) sur les threads, pour éviter les synchronisations de chaque nombre aléatoire. P>
Pour cette approche, vous n'avez pas besoin d'un filetage avancé. Il suffit d'utiliser une classe de fil régulière, pas de piscine, pas de bibliothèque. La seule chose dont vous avez besoin est (malheureusement) non dans la bibliothèque standard est une classe de file d'attente de blocage (la classe de file d'attente dans System.Collections n'est pas bonne). CodeProject fournit une implémentation raisonnablement recherchée d'un; Il y a probablement d'autres. P>
L'autre question à considérer est la commutation de contexte. Si vous n'avez pas choisi l'architecture ci-dessus (probablement une erreur imo de ce que vous avez dit), vous essayez ensuite de courir beaucoup de calculs en parallèle, ce qui dépasserait de loin votre nombre de transformateurs. Cela serait désastreux que beaucoup de temps de processeur qui calculait les réponses précédemment est désormais consacré à la commutation entre les threads. Si vous avez eu un fichier IO après chaque calcul, cela pourrait peut-être être fait ASYNC (mais vous utiliseriez ensuite une file d'attente et passez des éléments à stocker dans un composant dédié).
Le calcul de Monte Carlo est entièrement lié à CPU, vous dites donc que je devrais toujours mapper 1 fil à 1 CPU sur la boîte il n'y a jamais un avantage pour aller> 1 threads par cpu? Sauf si un thread n'attend que quelque chose, cela permettrait aux édifices des commutateurs contextuels, mais dans mon cas, il n'y a aucun avantage en fait, ce serait pire performance.
Correct. S'il n'y a vraiment pas d'IO dans ces fils, vous utilisez plusieurs threads par processeur ralentissez-le, non pas accéléré.
OK merci. Quelle est la différence entre Core et CPU? Le filetage hyper fait également une différence? Je développe et profilez-moi sur ma propre machine A: Intel Core 2 Duo E6550 @ 2.33 GHz (dans le gestionnaire de périphériques, il présente 2 processeurs). Le serveur est un: AMD Opteron 275 (dans le gestionnaire de périphériques, il affiche 4 processeurs). En C # Si je fais un environnement.Processorcount et commencez ce nombre de threads, c'est que la voie à suivre? De plus, si je devais proposer de nouveaux matériels pour cette application critique de mission au travail, à quoi devrais-je envisager. Merci
De plus, mon PC est Windows XP, le serveur est Windows Server 2003 32 bit. Je viens de lire sur le système d'exploitation Windows HPC et je me demande si cela en vaut la peine pour cette migration. De plus, si cette application est entièrement liée à la CPU, la mémoire n'est-elle probablement pas accélérée à X64, fonctionne comme Math.SQRT, multiplications matricielles, la division soit plus rapide sur x64?
Vous devriez considérer le processeur, le noyau et le processeur comme synonymes et ne compter que le total des cœurs (c'est-à-dire deux croustilles de la CPU avec chaque cœurs de deux cœurs sont identiques à un processeur avec quatre cœurs, à peu près). Windows affiche chaque noyau (de manière appropriée) en tant que CPU. Avec hyperthreading, chaque noyau peut apparaître comme deux processeurs; Désactiver HT si cela se produit. Environnement.Processorcount doit vous donner le même numéro que le chef de la tâche. Ignorer Windows HPC: il est utile uniquement pour les grappes de plusieurs ordinateurs serveurs. X64: Cela dépend vraiment de l'application. Pour les opérations à virgule flottante, il ne devrait y avoir aucune différence.
Une autre remarque: n'essayez pas de surgirer cette application. Cela ressemble vraiment à un étui à usage multi-threading standard avec quelques travaux séparables, de sorte que les approches vraiment anciennes et établies vont très bien fonctionner. Obtenez cela pour travailler et une vitesse de trois (sur quatre processeurs) serait excellente.
Le threading va être compliqué. Vous devrez casser votre programme en unités logiques pouvant être exécutées sur leurs propres threads et vous devrez faire face à des problèmes de concurrence qui émergent. P>
La bibliothèque d'extension parallèle devrait vous permettre de paralléler votre programme en modifiant certaines de vos boucles pour parallèle.for forts> boucles. Si vous voulez voir comment cela fonctionne, Anders Hejlsberg et Joe Duffy offrent une bonne introduction dans leur vidéo de 30 minutes ici: P>
Le threadpool, comme son nom l'indique, est un bassin de fils. L'utilisation de la threadpool pour obtenir vos threads présente des avantages. La mise en commun du fil vous permet d'utiliser des threads plus efficacement en fournissant votre application avec un pool de threads de travailleur gérés par le système. P>
Hmm, je ne pense pas que l'utilisation de la threadpool soit plus compliquée que le filetage manuel - ce que je pense est quelque chose que vous vouliez dire, mais laissé de côté? En comparant les threads de threadpool et de manutention manuellement, le threadpool est plus efficace (car il recycle des threads remplis, la création de fil est coûteuse) et est plus facile à utiliser - surtout si vous obtenez des délégués. Cela dit, je ne peux pas parler de le comparer aux bibliothèques parallèles - je ne voulais tout simplement pas que le threadpool ait un mauvais nom :-)
réponse fantastique merci! Cela fait un sens parfait. Maintenant, la question est de devrais-je utiliser ajouter une plage ou de trouver une collection threadsafe qui me permet d'accumuler la liste des nombres aléatoires (doubles), l'ordre est sans importance, mais je dois trier périodiquement les résultats et accroître un résultat à un certain centile et Recherchez les critères de convergence Pour tester une résiliation anticipée de la simulation, j'ai besoin de le faire pour chaque parallèle .Pour Path fonctionnant, puis annulez toutes les exécutions parallèles immédiatement si aucun traitement supplémentaire n'est requis, aucune idée de quoi faire?
Je n'ai pas immédiatement de réponse pour cela. Les chèques d'état périodiques et l'annulation des tâches parallèles en attente / en cours d'exécution constituent un gros sujet. Je vous recommande de poster une nouvelle question.
Bien que, découvrez blogs.msdn.com/pfxxteam/archive/ 2009/05/22/9635790.aspx
Sur quelle machine utilisez-vous? Pourrait recevoir une partie de l'augmentation de la vitesse requise du matériel mis à niveau.
Ceci est sur une AMD OPTERON 275, 4 CPU, je pense, pas sûr combien de cœurs. Windows Server 2003 SP2 32 bits