C# Mersenne Twister 随机整数生成器实现(SFMT)蒙特卡罗模拟

发布于 2024-07-29 05:35:38 字数 1367 浏览 4 评论 0原文

到目前为止,我一直在使用此处找到的 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()< /code>,它生成一个介于(并包括)0 和 2^20 之间的整数,以保存上面的转换和移位,但我不明白数学。 我到底该怎么做呢?

另外,使用 uint 是否会比 int 更快,或者只是可寻址数字的问题? 因为我只需要最多 1048576,所以我只关心速度。

此外,这将在带有 .NET 2 的 Windows Server 2003 R2 SP2(32 位)机器上运行。处理器是 AMD Opteron 275(4 核)。

So far I've been using the C# Mersenne Twister found here to generate random numbers:

http://www.centerspace.net/resources.php

I just discovered SFMT which is supposed to be twice as fast here:

http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/

Can anyone point me at a C# implementation of SFMT?

My requirements are to generate an integer between (and including) 0 and 2^20 (1048576).

I need to do this trillions of times everyday for a simulation running on a 24 hour clock so I am prepared to spend days tweaking this to perfection.

Currently I've tweaked the Center Space Mersenne Twister by adding a new method to fit my requirements:

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 shift but I don't understand the mathematics. Exactly how can I do this?

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.

Also this will be running on a Windows Server 2003 R2 SP2 (32bit) box with .NET 2. Processor is AMD Opteron 275 (4 core).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

无法回应 2024-08-05 05:35:38

您可以做的是从您发现的链接下载源关于代码项目。 解压缩它,在 Visual Studio 中加载解决方案并编译它。 这将为您提供源代码、非托管 c dll 和 .lib 文件。

您可以 P/Invoke 此 dll 中的函数(仅导出 5 个简单函数,您只需要其中两个)或者您可以使用此 dll、lib 和 SFMT 头文件来创建您可以使用的托管包装器 dll在没有 P/Invoke 的 C# 中。 我刚刚尝试了这个方法,而且做起来非常简单。 没有涉及明确的编组。

就是这样。 下载并编译(除了 dll 之外,您还需要头文件和创建的 lib 文件),创建一个新的 C++ CLR 类库项目。 称之为 WrapSFMT 或其他名称。 转到项目属性。 在 C++/预编译头下,更改为“不使用预编译头”。 在链接器/常规/附加库目录下,输入 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);
};
}

这些声明将在您的类中的方法。 现在编辑 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 在路径中,应该不会有任何问题。

What you can do is download the source from the link you 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.

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.

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.

Edit WrapSFMT.h to read as follows:

#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:

#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.

以往的大感动 2024-08-05 05:35:38

您可以在以下位置找到 SFMT(以及其他 RNG 算法)的 C# 实现:
http://rei.to/random.html
页面和源代码注释都是日文的,但你应该能够理解。

您还可以在以下位置找到该页面的 Google 翻译版本(英语):
http://translate .google.com/translate?hl=zh-CN&sl=ja&u=http://rei.to/random.html

You can find a C# implementation of SFMT (plus other RNG algorithms) at...
http://rei.to/random.html
The page and source code comments are in Japanese but you should be able to figure it out.

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

时光是把杀猪刀 2024-08-05 05:35:38

我真的没有看到你在这里的速度问题。 在我的机器(Core 2 Duo T7200 @ 2 GHz)上,使用 MT19937 或 MT19937-64 生成随机整数大约需要 20 ns(平均而言,绘制 50000 个数字时)。 因此每天大约为 4.32 × 1012(即大约 4万亿)。 这是针对一个核心的。 用Java。 因此,我认为您可以预期其性能足以满足您的需求。

实际回答您的问题:我不知道 SFMT 的 C# 实现,但将 C 代码转换为 C# 应该相当简单。 但是,您并没有获得太多收益,因为 SFMT 针对 SIMD 进行了优化,而 C# 目前不直接支持这一点。

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 trillion numbers) 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.

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.

蓬勃野心 2024-08-05 05:35:38

是否有原因无法将 C 实现编译到 DLL 中并从 C# 代码中调用它?

编辑:

抱歉,但我对 C(实际上是 C#)的了解非常有限,但“如何创建 C dll”可能会在这里得到解答:http:// www.kapilik.com/2007/09/17/how-to-create-a-simple-win32-dl​​l-using-visual-c-2005/ 以及可以通过分析代码来检查速度。

Is there a reason you can't compile the C implementation into a DLL and call this from your C# code?

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.

[浮城] 2024-08-05 05:35:38

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

具体来说,这个 (作者:Cory Nelson)可能会有用。

Maybe this is what you're looking for?
There is a list of several implementations.

Specifically, this one (by Cory Nelson) might be useful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文