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 2Windows 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-dl​​l-using-visual-c-2005 /以及通过分析代码来检查速度。

也许这就是你要找的? 有几个实现的列表。

具体来说, 这个 (由Cory Nelson)可能是有用的。