Jusqu'à présent, j'utilise le C # Mersenne Twister trouvé ici pour générer des nombres aléatoires:
http://www.centerspace.net/resources.php p> < p> Je viens de découvrir http://www.math.sci.hiroshima-acc.jp/~m-mat/mt/sfmt/ p> Quelqu'un peut-il me dire à une implémentation C # Sfmt strong>? P> Mes exigences sont de générer un entier entre (et y compris) 0 et 2 ^ 20 (1048576). P> J'ai besoin de faire cela actuellement j'ai modifié l'espace central Mersenne Twis En ajoutant une nouvelle méthode pour adapter mes besoins: p> à l'aide de la méthode utilise également un uint ut va être plus rapide que INT fort> ou est juste une question de nombres adressables? Parce que je n'ai besoin que de 1048576, je ne suis que sur la vitesse. P> Ce sera également en cours d'exécution sur une boîte genrand_int32 () code> J'aimerais produire ma propre version, < Code> Genrand_int20 () Code>, qui génère un entier entre (et y compris) 0 et 2 ^ 20 pour économiser sur la coutée
5 Réponses :
Je ne vois pas vraiment votre problème avec la vitesse ici. Sur ma machine (Core 2 Duo T7200 @ 2 GHz) Créer un entier aléatoire avec MT19937 ou MT19937-64 prend environ 20 NS (en moyenne, lors du dessin 50000 numéros). Donc, ce serait environ 4,32 × 10 12 sup> (environ 4 billion em> chiffres) par jour. Et c'est pour un noyau. Avec Java. Je pense donc que vous pouvez vous attendre à ce que la performance soit plus que suffisante pour vos besoins. P>
Pour répondre à votre question: je ne connais pas une implémentation C # de SFMT, mais la conversion du code C en C # devrait être assez simple. Cependant, vous n'en gagnez pas beaucoup, car SFMT est optimisé pour SIMD et C # ne le supporte actuellement pas directement. P>
J'ai calculé les exigences quotidiennes au nombre aléatoire pour cette simulation pour soutenir l'entreprise à 1 645 668 000 000 000. La simulation fait beaucoup d'autres choses principalement la multiplication de matrice, donc je ne peux pas consacrer tout le temps de la CPU à une génération de nombres aléatoires, je souhaite évidemment minimiser le nombre de numéros aléatoires autant que possible, d'où la question Stackoverflow.
Eh bien, vous avez toujours de multiples noyaux et des simulations de Monte Carlo ont tendance à être assez parallélisables. Je dirais que vous devriez d'abord aller de l'avant et résoudre votre problème et revisiter des parties individuelles de la solution s'ils prouvent un problème de performance.
Pour SFMT, je n'ai pas réalisé que, peut-être que ma meilleure approche est d'essayer de compiler la version C ici: math.sci.hiroshima-u.ac.jp/~m-mat/bin/dl/... < / a> puis utilisez-le de ma simulation de mon C # Monte Carlo en quelque sorte. Je ne suis pas familier avec C / C ++ Comment compiler leur SRC et comment l'utiliser de C #.
Merci @johannes, ma mise en œuvre peut utiliser 3 cœurs (du 4 sur la boîte), donc oui, il s'agira d'une implémentation parallèle, même à ce moment-là (avec une victoire 3 fois), je me rapproche de la limite de temps d'exécution quotidienne de 24 heures dans le app. J'ai mis une demande de nouveau serveur, plus de CPU, etc., mais le rythme de cette banque fonctionne, c'est un processus très lent et on m'a demandé d'optimiser maintenant.
On dirait que vous pouvez utiliser un bon cas de la règle d'optimisation des séquences.
Si vous envisagez de tirer parti de plusieurs cœurs, soyez conscient que les lignes de cache peuvent vous ruiner pour vous. Jetez un coup d'œil à cet article: ddj.com/go-parallel / Article / ...
y a-t-il une raison pour laquelle vous ne pouvez pas compiler la mise en œuvre C dans une DLL et l'appeler à partir de votre code C #? P>
Je suis désolé, mais je n'ai que des connaissances très limitées de C (et en effet C #), mais le "Comment créer une DLL C" peut être répondu ici: http://www.kapilik.com/ 2007/09/17 / HOW-TO-CRÉCRISER-A-SIMPLE-WIN32-DLL-UTILISATION-VISUAL-C-2005 / ET LE COMMENT FAST peut être vérifié en profilant du code. P>
Salut Patrick, je n'ai jamais utilisé c, je ne sais pas comment faire ça? et utiliser de C #, suis-je susceptible de perdre beaucoup de performances par ce que je suppose que .Net fait quelques enveloppements de mes appels de C # à la DLL C sous-jacente?
J'imaginerais que P / invoquer à plusieurs reprises dans un code non géré n'engage pas une jolie performance surprise.
Je viens de découvrir ceci: codeProject.com/kb/dll/sfmt_dll.aspx ? msg = 3130186 je me demande si cela pourrait s'avérer utile pour ma situation
J'ai également remarqué une implémentation F # sur la Botttom ici ici en.wikipedia.org/wiki/mersenne_twister Non idée comment utiliser F # mais pourrait valoir la peine d'apprendre et d'analyser.
Eh bien, les deux f # et c # ciblent le CLR et je m'attendrais à ce que le code F # soit réellement plus lent que c #. Vous pouvez toujours regarder le code généré avec le réflecteur.
Peut-être est ce que vous cherchez? Il existe une liste de plusieurs implémentations. P>
Spécifiquement, Celui-ci a > (par Cory Nelson) pourrait être utile. P>
J'ai téléchargé ses DLL et a essayé de les ajouter comme référence à mon projet C # je reçois: --------------------------- Microsoft Visual Studio - -------------------------- Une référence à 'sfmtc.dll' n'a pas pu être ajoutée. Assurez-vous que le fichier est accessible et qu'il s'agit d'un ensemble valide ou d'un composant COM. --------------------------- D'ACCORD ---------------------- ----- Des idées? Sur la façon d'utiliser cela et appelez-le de la manière la plus efficace de Visual Studio
Ok j'ai placé la DLL dans mon dossier bin et que vous avez du code: [dllimport ("sfmtc.dll")] statique extern uint32 gen_rand32 (); Cet appel sans erreur, mais tout ce que je récupère, c'est 0, jamais d'autre numéro.
Si vous souhaitez utiliser p / invoke, vous devrez invoquer deux fonctions, init_gen_rand (uint32), initialisation du générateur avec une graine, puis vous pouvez appeler GEN_RAND32 () autant que vous le souhaitez. (Mais vous ne devriez probablement pas dépasser la période de Twister de Mersenne)
Pour votre premier commentaire, si vous souhaitez référencer la DLL dans votre projet C # et éviter P / Invoke, vous devrez créer une DLL d'emballage avec C ++ / CLI et référence. Ce n'est pas difficile. Je vais éditer la réponse pour vous montrer comment.
Impressionnant @R Ubben exactement ce que je cherche, j'essaie la route Dllimport pour le moment, qui est susceptible d'être plus rapide? Aussi quelle est ma meilleure façon de graver cela? Et comment partir pour le code multithreaded? Ou est-ce que je pouvais juste init_gen_rand une fois pour la vie du programme avant de filtrer les threads, alors chaque thread indépendant peut apporter des appels à Gen_Rand32 () à condition que Calling Gen_Rand32 () est le fil de sécurité? Sinon, je ne vois pas comment séparer cela et donner à chaque thread de manière efficace son propre générateur de nombres aléatoires afin qu'ils soient indépendants?
Hmm j'ai expliqué cela en utilisant Dllimport de la SFMT et il est environ deux fois plus lent que mon C # MT, je me demande si une version C ++ / CLI serait beaucoup plus rapide.
Pour la graine, je pense que la plupart des gens utilisent quelque chose comme System.Environment.TickCount ou System.DateTime.now.Ticks - Rappelez-vous simplement, initialiser avec le même numéro vous donnera la même séquence de nombres aléatoires. Une meilleure graine viendrait de RngCryptoServiceProvider, vérifiez MSDN pour plus de détails. En ce qui concerne la filetage, pourquoi ne pas donner à chaque fil son propre générateur de nombres aléatoires? Assurez-vous simplement qu'ils obtiennent différentes graines.
Je n'ai pas comparé la DLL SFMT, mais votre machine pourrait ne pas prendre en charge SSE2, ce qui est ce que cette DLL utilise. Vérifiez l'article Wikipedia sur SSE2.
Vous pouvez trouver une implémentation C # de SFMT (plus d'autres algorithmes RNG) à ... http://rei.to/random.html Les commentaires de la page et de la source sont en japonais mais vous devriez être capable de le comprendre. P>
Vous pouvez également trouver une version traduite de Google (en anglais) de la page à ... http://translate.google.com /Translate?hl=fr&sl=ja&u=http://rei.to/random.html P>
Un nombre de 20 bits représentera la plage de 0 à 2 ^ 20-1 inclusive, 2 ^ 20 nécessite 21 bits représentant (un 1 suivi de 20 zéros)
Nifle: Ne confondez pas la période i> du générateur (qui est la longueur de la séquence) avec un intervalle i> dans lequel vous voulez des nombres aléatoires.
@Patrick Merci que vous êtes correct 2 ^ 20-1 est ce dont j'ai besoin, j'ai besoin d'indexer au hasard dans un tableau de longueur 2 ^ 20.
@Nifle Oui, je sais, j'ai demandé si quelqu'un peut me signaler à une implémentation C # de SFMT.