C#Mersenne Twister随机整数发生器实现(SFMT)蒙特卡罗模拟
到目前为止,我一直在使用此处的C# Mersenne Twister生成随机数:
http://www.centerspace.net/resources.php
我刚发现SFMT的速度应该是这里的两倍:
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/
有人能指出我在SFMT的C#实现吗?
我的要求是在(和包括)0和2 ^ 20(1048576)之间生成一个整数。
我需要每天花费数万亿次进行24小时制模拟,所以我准备好花几天时间来完善它。
目前我通过添加一种符合我要求的新方法调整了Center Space Mersenne Twister:
public uint Next20() { return (uint)(genrand_int32() >> 12); }
使用方法genrand_int32()
我想生成我自己的版本genrand_int20()
,它在(和包括)0和2 ^ 20之间生成一个整数,以保存在上面的转换和转移但我不懂数学。 究竟我该怎么做?
还使用uint比int更快 ,或者只是可寻址数字的问题? 因为我只需要1048576,我只关心速度。
此外,它将在带有.NET 2的Windows Server 2003 R2 SP2(32位)盒上运行。处理器是AMD Opteron 275 (4核) 。
您可以做的是从您在Code Project上发现的链接下载源代码。 解压缩,在Visual Studio中加载解决方案并进行编译。 这将为您提供源,非托管c dll和.lib文件。
你可以在这个dll中调用/调用函数,(只导出5个简单函数,你只需要两个)或者你可以使用这个dll,lib和SFMT头文件创建一个你可以使用的托管包装器dll在没有P / Invoke的C#中。 我只是尝试了这种方法,这很简单。 没有明确的编组参与。
这是如何做。 下载并编译源代码 (需要头文件和除dll之外创建的lib文件)后,创建一个新的C ++ CLR类库项目。 称之为WrapSFMT或其他东西。 去项目属性。 在C ++ / Precompiled Headers下,更改为“Not using precompiled headers”。 在链接器/常规/附加库目录下,输入SFMT.lib的路径。 在“链接器/输入/附加依赖项”下,添加SFMT.lib。 关闭属性页面。 将SFMT.h复制到项目文件夹并将其包含在项目中。
编辑WrapSFMT.h如下:
#pragma once #include "SFMT.H" using namespace System; namespace WrapSFMT { public ref class SRandom { public:SRandom(UInt32); public:UInt32 Rand32(void); }; }
这些声明了您class级中的方法。 现在编辑WrapSFMT.cpp来阅读:
#include "WrapSFMT.h" namespace WrapSFMT { SRandom::SRandom(UInt32 seed) { init_gen_rand(seed); } UInt32 SRandom::Rand32() { return gen_rand32(); } }
这些实现了您在头文件中声明的方法。 您所做的只是从SFMT.dll调用函数,C ++ / CLI自动处理从非托管到托管的转换。 现在,您应该能够构建WrapSFMT.dll并在C#项目中引用它。 确保SFMT.dll在路径中,您应该没有问题。
您可以在… http://rei.to/random.html找到SFMT的C#实现(以及其他RNG算法)页面和源代码注释是日文的,但您应该能够弄明白。
您还可以在http://translate.google.com/translate?hl=zh-CN&sl=ja&u=http://rei.to/random.html找到该页面的Google翻译版本(英文版)。
我真的没有看到你的速度问题。 在我的机器(Core 2 Duo T7200 @ 2 GHz)上,使用MT19937或MT19937-64生成随机整数大约需要20 ns(平均而言,绘制50000个数字时)。 因此,每天约为4,32×10 12 (约4 万亿个数字)。 这是一个核心。 用Java。 所以我认为您可以期望性能足以满足您的需求。
要真正回答你的问题:我不知道SFMT的C#实现,但是将C代码转换为C#应该相当简单。 但是,由于SFMT针对SIMD进行了优化而C#目前不直接支持,因此您获得的收益并不高。
有没有理由你不能将C实现编译成DLL并从你的C#代码调用它?
编辑:
对不起,但我对C(实际上是C#)知之甚少,但“如何创建C dll”可以在这里得到解答: http : //www.kapilik.com/2007/09/ 17 /如何创建一个简单的win32-dll-using-visual-c-2005 /以及通过分析代码来检查速度。
也许这就是你要找的? 有几个实现的列表。
具体来说, 这个 (由Cory Nelson)可能是有用的。