C# Mersenne Twister 随机整数生成器实现(SFMT)蒙特卡罗模拟
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1166408/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# Mersenne Twister random integer generator implementation (SFMT) monte carlo simulation
提问by m3ntat
So far I've been using the C# Mersenne Twisterfound here to generate random numbers:
到目前为止,我一直在使用这里找到的 C# Mersenne Twister来生成随机数:
http://www.centerspace.net/resources.php
http://www.centerspace.net/resources.php
I just discovered SFMTwhich is supposed to be twice as fast here:
我刚刚发现了SFMT,它的速度应该是这里的两倍:
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/
Can anyone point me at a C# implementation of SFMT?
谁能给我指出 SFMT 的 C# 实现?
My requirements are to generate an integer between (and including) 0 and 2^20 (1048576).
我的要求是生成一个介于(包括)0 和 2^20 (1048576) 之间的整数。
I need to do this trillions of times everydayfor a simulation running on a 24 hour clock so I am prepared to spend days tweaking this to perfection.
我需要每天执行数万亿次以 24 小时制运行的模拟,因此我准备花几天时间将其调整到完美。
Currently I've tweaked the Center Space Mersenne Twister by adding a new method to fit my requirements:
目前,我通过添加一种新方法来满足我的要求,对 Center Space Mersenne Twister 进行了调整:
public uint Next20()
{
return (uint)(genrand_int32() >> 12);
}
Using the method genrand_int32()
I'd like to produce my own version, genrand_int20()
, that generates an integer between (and including) 0 and 2^20 to save on the cast above and shiftbut I don't understand the mathematics. Exactly how can I do this?
使用genrand_int32()
我想生成我自己的版本的方法genrand_int20()
,生成一个介于(包括)0 和 2^20 之间的整数以节省上面的转换和移位,但我不明白数学。我怎么能做到这一点?
Also is using an uint going to be faster that int, or is just a matter of addressable numbers? Because I only need up to 1048576, I am only concerned with speed.
还使用uint 会比 int 更快,还是只是可寻址数字的问题?因为我最多只需要1048576,所以我只关心速度。
Also this will be running on a Windows Server 2003 R2 SP2 (32bit) box with .NET 2. Processor is AMD Opteron 275(4 core).
此外,这将在带有 .NET 2的Windows Server 2003 R2 SP2(32 位)机器上运行。处理器是AMD Opteron 275(4 核)。
采纳答案by R Ubben
What you can do is download the source from the linkyou discovered on Code Project. Unzip it, load the solution in Visual Studio and compile it. This will give you source, an unmanaged c dll and a .lib file.
您可以做的是从您在 Code Project 上发现的链接下载源代码。解压缩它,在 Visual Studio 中加载解决方案并编译它。这将为您提供源代码、一个非托管的 c dll 和一个 .lib 文件。
You can P/Invoke the functions in this dll, (there are only 5 simple functions exported, of which you need only two) or you can use this dll, lib, and the SFMT header file to create a managed wrapper dll you can use in C# without P/Invoke. I just tried this method and it was very simple to do. There was no explicit marshalling involved.
你可以P/Invoke这个dll中的函数,(只导出了5个简单的函数,其中你只需要两个)或者你可以使用这个dll,lib和SFMT头文件来创建一个你可以使用的托管包装dll在没有 P/Invoke 的 C# 中。我刚试过这个方法,做起来很简单。没有涉及明确的编组。
Here's how. Once you have downloaded and compiled the source(you need the header and the lib file that is created in addition to the dll) create a new C++ CLR Class Library project. Call it WrapSFMT or something. Go the project properties. Under C++/Precompiled Headers, change to "Not using precompiled headers." Under the Linker/General/Additional Library Directories, enter the path to the SFMT.lib. Under Linker/Input/Additional Dependencies, add SFMT.lib. Close the property pages. Copy SFMT.h to your project folder and include it in the project.
就是这样。下载并编译源代码(除了 dll 之外,您还需要头文件和创建的 lib 文件)后,创建一个新的 C++ CLR 类库项目。称之为 WrapSFMT 或其他什么。转到项目属性。在 C++/预编译头文件下,更改为“不使用预编译头文件”。在 Linker/General/Additional Library Directory 下,输入 SFMT.lib 的路径。在链接器/输入/附加依赖项下,添加 SFMT.lib。关闭属性页。将 SFMT.h 复制到您的项目文件夹并将其包含在项目中。
Edit WrapSFMT.h to read as follows:
编辑 WrapSFMT.h 如下:
#pragma once
#include "SFMT.H"
using namespace System;
namespace WrapSFMT {
public ref class SRandom
{
public:SRandom(UInt32);
public:UInt32 Rand32(void);
};
}
These declare the methods that will be in your class. Now edit WrapSFMT.cpp to read:
这些声明将在您的类中的方法。现在编辑 WrapSFMT.cpp 以阅读:
#include "WrapSFMT.h"
namespace WrapSFMT {
SRandom::SRandom(UInt32 seed)
{
init_gen_rand(seed);
}
UInt32 SRandom::Rand32()
{
return gen_rand32();
}
}
These implement the methods you declared in the header file. All you are doing is calling functions from the SFMT.dll, and C++/CLI is automatically handling the conversion from unmanaged to managed. Now you should be able to build the WrapSFMT.dll and reference it in your C# project. Make sure the SFMT.dll is in the path, and you should have no problems.
这些实现了您在头文件中声明的方法。您所做的只是从 SFMT.dll 调用函数,C++/CLI 会自动处理从非托管到托管的转换。现在您应该能够构建 WrapSFMT.dll 并在您的 C# 项目中引用它。确保 SFMT.dll 在路径中,您应该没有问题。
回答by Joey
I don't really see your problem with speed here. On my machine (Core 2 Duo T7200 @ 2 GHz) generating a random integer with MT19937 or MT19937-64 takes around 20 ns (on average, when drawing 50000 numbers). So that'd be around 4,32 × 1012(so around 4 trillionnumbers) a day. And that's for one core. With Java. So I think you can expect the performance to be more than adequate for your needs.
我真的没有看到你在这里的速度问题。在我的机器(Core 2 Duo T7200 @ 2 GHz)上,用 MT19937 或 MT19937-64 生成一个随机整数大约需要 20 ns(平均,当绘制 50000 个数字时)。所以这大约是每天 4,32 × 10 12(所以大约 4万亿个数字)。这是一个核心。用Java。因此,我认为您可以期望性能足以满足您的需求。
To actually answer your question: I don't know of a C# implementation of SFMT, but conversion of the C code to C# should be fairly straightforward. However, you're not gaining much, as SFMT is optimized for SIMD and C# currently doesn't support this directly.
实际回答您的问题:我不知道 SFMT 的 C# 实现,但是将 C 代码转换为 C# 应该相当简单。但是,您并没有获得多少收益,因为 SFMT 已针对 SIMD 进行了优化,而 C# 目前不直接支持这一点。
回答by Patrick McDonald
Is there a reason you can't compile the C implementation into a DLL and call this from your C# code?
您是否有理由无法将 C 实现编译为 DLL 并从您的 C# 代码中调用它?
EDIT:
编辑:
I'm sorry, but I have only a very limited knowledge of C (and indeed C#), but the "How to create a C dll" may be answered here: http://www.kapilik.com/2007/09/17/how-to-create-a-simple-win32-dll-using-visual-c-2005/and the how fast can be checked by profiling the code.
抱歉,我对 C(实际上也是 C#)的了解非常有限,但是“如何创建 C dll”可以在这里回答:http: //www.kapilik.com/2007/09/ 17/how-to-create-a-simple-win32-dll-using-visual-c-2005/以及通过分析代码可以检查多快。
回答by Francisco
回答by QZ1
You can find a C# implementation of SFMT (plus other RNG algorithms) at... http://rei.to/random.htmlThe page and source code comments are in Japanese but you should be able to figure it out.
您可以在以下位置找到 SFMT(以及其他 RNG 算法)的 C# 实现... http://rei.to/random.html页面和源代码注释是日语,但您应该能够弄清楚。
You can also find a Google-translated version (to English) of the page at... http://translate.google.com/translate?hl=en&sl=ja&u=http://rei.to/random.html
您还可以在以下位置找到该页面的 Google 翻译版本(英语)... http://translate.google.com/translate?hl=en&sl=ja&u=http://rei.to/random.html