8
votes

C # Optimisation des risques incrémentiels incrémentiels de Monte Carlo, nombre aléatoire, exécution parallèle

Ma tâche actuelle consiste à optimiser un simulation de Monte Carlo que Calcule les chiffres de l'adéquation du capital par région pour un ensemble de débiteurs.

Il gère environ 10 x trop lent pour l'endroit où il devra être en production et à des numéros ou à des courses quotidiennes requises. De plus, la granularité des chiffres de résultat devra être améliorée au bureau éventuellement du niveau de livre à un moment donné, le code que j'ai donné est essentiellement un prototype utilisé par des unités d'affaires dans une capacité semi-production.

L'application est actuellement à un seul fileté simple , donc je devrai le faire multi-threads , peut regarder system.threading.threadpool ou le Microsoft Extensions parallèles Bibliothèque, mais je suis contraint à .NET. 2 Sur le serveur de cette banque, j'ai peut-être dû prendre en compte le port de ce type, http: // www.codeproject.com/kb/cs/aforge_parallel.aspx .

J'essaye de mon mieux pour les amener à passer à .NET 3.5 SP1, mais c'est un exercice majeur dans une organisation de cette taille et pourrait ne pas être possible dans mes cadres de temps de contrat.

J'ai profilé l'application à l'aide de l'essai de DotTrace < / a> ( http://www.jetbrains.com/profiler ). Quels autres bons profileurs existent? Ceux libres?

Beaucoup de temps d'exécution est dépensé générant des nombres aléatoires uniformes , puis traduisant ceci en un nombre aléatoire distribué normalement. Ils utilisent un C # Mersenne Twister Mise en œuvre. Je ne sais pas où ils l'ont eu ou si c'est la meilleure façon d'y aller (ou de la meilleure mise en œuvre) pour générer des nombres aléatoires uniformes. Ensuite, ceci est traduit vers une version normalement distribuée à utiliser dans le calcul (je n'ai pas encore plongé au code de traduction).

Aussi quelle est l'expérience en utilisant ce qui suit?

  • http://quantlib.org

  • http://www.qlnet.org (port C # de Quantlib) ou

  • http://www.boost.org

    Toute alternative que vous connaissez? Je suis un développeur C # préférerait que c #, mais un wrapper à C ++ ne devrait pas être un problème, devrait-il?

    Peut-être encore plus rapidement des implémentations C ++. Je pense que certaines de ces bibliothèques auront la méthode la plus rapide pour générer directement des nombres aléatoires distribués normalement, sans l'étape de traduction. En outre, ils peuvent avoir d'autres fonctions qui seront utiles dans les calculs suivants.

    Aussi l'ordinateur Ceci est activé est un Quad Core Opteron 275, 8 Go de mémoire de 8 Go, mais Windows Server 2003 Entreprise 32 bits . Devrais-je les conseiller de passer à un système d'exploitation 64 bits ? Tous les liens vers des articles en faveur de cette décision seraient vraiment appréciés.

    Quoi qu'il en soit, tout conseil et aide que vous ayez peut-être vraiment apprécié.


4 commentaires

Pourquoi croyez-vous que jeter plus de threads au problème améliorera les questions?


Actuellement, le code est un seul fileté en cours d'exécution sur une boîte à quad à quad, OPTERON 275 pour être précis. Le code est écrit pour exécuter séquentiellement, le compilateur ou le CLR ou le jeu d'instructions de la CPU peut prendre la meilleure estimation de la manière de prendre ce code et de tenter de lancer des parties de celui-ci en parallèle pour améliorer les performances. Ou je peux écrire ce code pour fonctionner dans un modèle parallèle fileté si efficacement suggérant au CLR, compilateur, CPU ce qui peut être exécuté simultanément et laisser ces instructions de niveau inférieur à optimiser l'exécution. Tes pensées?


8 Go de mémoire est de 4 Go de déchets sur 32 bits ...


Tout le monde a un aperçu de la bibliothèque d'extension parallèle, toute personne utilisée parallèle.Pour la version Microsoft vs ceci codeproject.com/kb/cs/aforge_parallel.aspx version opensource est également à la recherche d'une personne bonne avec des fils pour peser et comparer avec les options de filetage .NET? Parce que je suis nouveau à la programmation multi-threadé


4 Réponses :


1
votes

Avez-vous envisagé de pointer un profileur à votre code ? J'ai vu des cas où il y a des corrections simples obtiennent des améliorations très significatives. Comme changer quelques propriétés dans les champs.


2 commentaires

J'ai essayé avec le procès de DotTrace, mais les résultats n'étaient pas ce granulaire, j'aurai un essai avec redgate si elles ont un essai gratuit?


Je pense qu'ils font, les fourmis ont sauvé la journée pour moi un tas de fois.



0
votes

Être contraint d'utiliser .NET En premier lieu pour une simulation à grande échelle va vous coûter tout à fait un peu de performance à l'avant ... mais cela dit ...

Si vous exécutez une implémentation pure C # de la Twister Mersenne, il est probable que vous ayez du mal à modifier toutes les performances que vous pouvez en sortir. Si vous consultez la mersenne Twister Mise en œuvre de référence Vous verrez qu'ils ont une version C fortement optimisée pour les processeurs capables de SSE - c'est très rapide. Je ne crois pas que ce soit possible dans C # (ou au moins, je ne suis pas conscient de la manière de forcer l'utilisation des instructions SSE avec ce niveau d'optimisation. Je suggérerais d'écrire un wrapper C ++ / CLI (ou un emballage P / invoke) autour des bibliothèques Twister Mersenne et voyez comment cela affecte votre performance. Toutefois, vous devrez faire attention à la gestion de votre performance, car j'ai vu d'autres postes ici sur cette question (bien que je ne puisse pas sembler de les trouver maintenant ...).

Je peux générer une certaine flamme pour le dire, mais si la performance est une préoccupation importante dans votre application, C / C ++ bien écrit va presque toujours être préférable à une langue gérée ou interprétée.


3 commentaires

En fait, je ne suis pas d'accord assez fort avec votre dernière déclaration ... C # peut jouer très très bien. Cela nécessite un profilage, mais dans mon expérience, il est beaucoup plus facile de profiler C # et de l'améliorer au point où il peut surperformer C et C ++ - surtout si vous prenez des avantages des bonnes bibliothèques et de comprendre comment écrire un code serré et très performant en c #.


Je veux aussi être de manière constructive :)


@Reed - Permettez-moi de clarifier - Je ne parle pas de la facilité de profilage, ni des outils disponibles, ni la difficulté d'optimiser. Je fais affirmer que pour tout programme écrit dans une langue interprétée ou gérée, il peut être prouvé qu'un programme égal fonctionnel avec des performances égales ou meilleures peut être écrite dans une langue non exploitée.



4
votes

J'ai trouvé la mersenne twister à être rapide. Le problème peut être dans l'algorithme (Box-Muller) pour transformer la distribution uniforme de la distribution gaussienne. L'algorithme standard ressemble à: xxx

où x1 et x2 sont des nombres aléatoires uniformes et Y1 et Y2 sont les sorties de distribution gaussiennes.

Les racines carrées sont lentes, mais le Trig est pire, et il est instable près de 0. page de taygeta sur le sujet donne un plus rapide (en pseudocode): xxx

S'ils n'utilisent pas quelque chose comme ça, vous pourrez peut-être accélérer les choses un peu en évitant les fonctions de Trig ou même pré-générer les nombres aléatoires.


3 commentaires

En tant que note, de nombreux transformateurs modernes ont une instruction de montage pour le calcul simultané du péché et du COS, et il est beaucoup moins cher que d'appeler à la fois séquentiellement. Il n'est pas disponible dans aucune bibliothèque standard, AFAIK, puisqu'il s'agit d'une fonctionnalité spécifique au processeur.


Merci à @r Ubben, est votre proposition identique à celle de ce en.wikipedia.org/wiki/box- Muller_transformation ou est-ce quelque chose de différent?


Oui, la forme polaire décrite. C'est un échantillonnage de rejet, de sorte que vous jetez des chiffres, mais cela finit toujours beaucoup plus vite. Bien que je travaille aussi dans la banque, je faisais cela pour le plaisir - illumination mondiale dans un traceur de rayons. Cela a fait une différence. Si la vitesse est toujours un problème, vous pouvez générer plusieurs centaines de millions d'euros entre les pistes quotidiennes, en fonction du nombre d'utilisations de la course et de les lire au besoin. Revenez ensuite à la génération si le magasin est épuisé.



0
votes

Mon expérience est que la performance relative de C # vs. C ++ dépend en grande partie de ce que vous faites. Une bonne discussion de cela ici:

C ++ Performance vs. Java / C #

Pour les boucles serrées qui font des mathématiques (disent des calculs de physique de vecteur) C ++ est un 2-3 fois plus rapide que c # bien que le perf puisse être dominé par les fonctions sous-jacentes telles que SQRT ().

J'ai pris une approche de langue mixte (RE) mise en œuvre du code le plus lent en C ++ / OpenMP avec une emballeuse gérée C ++ / CLI. Cela vous permet de «payer pour ce que vous utilisez».

Il y a un résumé de la manière d'envelopper Native C / C ++ avec C ++ / CLI ici:

http://msdn.microsoft.com/en-us/library /ms235281.aspx

Une fois que vous avez accroché au C ++ / CLI, il est assez facile de faire fonctionner les choses.


0 commentaires