8

これまでのところ、ここにある C# Mersenne Twisterを使用して乱数を生成してきました。

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

ここで2倍高速であるはずのSFMTを発見しました:

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

SFMT の C# 実装を教えてもらえますか?

私の要件は、0 と 2^20 (1048576) の間 (および含む) の整数を生成することです。

24 時間時計で実行されるシミュレーションでは、これを毎日何兆回も行う必要があるため、これを完全に微調整するのに何日も費やす準備ができています。

現在、私の要件に合わせて新しいメソッドを追加することで、センター スペース メルセンヌ ツイスターを微調整しました。

public uint Next20()
{            
    return (uint)(genrand_int32() >> 12);
}

メソッドを使用して、上記のキャストとシフトを節約するために 0 と 2^20 の間 (および 0 を含む) の整数を生成するgenrand_int32()独自のバージョン を生成したいのですが、数学がわかりません。正確にどうすればこれを行うことができますか?genrand_int20()

また、uint を使用すると int よりも高速になりますか、それとも単にアドレス指定可能な数値の問題ですか? 1048576 までしか必要ないので、速度だけに関心があります。

また、これは.NET 2 を搭載した Windows Server 2003 R2 SP2 (32 ビット) ボックスで実行されます。プロセッサはAMD Opteron 275 (4 コア)です。

4

5 に答える 5

5

できることは、Code Project で見つけたリンクからソースをダウンロードすることです。解凍し、ソリューションを Visual Studio にロードしてコンパイルします。これにより、ソース、アンマネージド c dll、および .lib ファイルが提供されます。

この dll 内の関数を P/Invoke することができます (エクスポートされる単純な関数は 5 つだけで、そのうち 2 つだけが必要です)。または、この dll、lib、および SFMT ヘッダー ファイルを使用して、使用できるマネージド ラッパー dll を作成できます。 P/Invoke を使用しない C# で。この方法を試してみたところ、非常に簡単でした。関連する明示的なマーシャリングはありませんでした。

方法は次のとおりです。ソースをダウンロードしてコンパイルしたら(dll に加えて作成されるヘッダーと lib ファイルが必要です)、新しい C++ CLR クラス ライブラリ プロジェクトを作成します。それをWrapSFMTか何かと呼んでください。プロジェクトのプロパティに移動します。C++/プリコンパイル済みヘッダーの下で、「プリコンパイル済みヘッダーを使用しない」に変更します。Linker/General/Additional Library Directories の下に、SFMT.lib へのパスを入力します。Linker/Input/Additional Dependencies の下に、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 がパスにあることを確認してください。問題はありません。

于 2009-07-22T20:08:08.273 に答える
2

SFMT (およびその他の RNG アルゴリズム) の C# 実装は、次の URL にあります。 http://rei.to/random.html ページとソース コードのコメントは日本語ですが、理解できるはずです。

このページの Google 翻訳版 (英語) は、... http://translate.google.com/translate?hl=en&sl=ja&u=http://rei.to/random.htmlにあります。

于 2011-03-24T18:41:12.733 に答える
0

多分これはあなたが探しているものですか?いくつかの実装のリストがあります。

具体的には、これ(Cory Nelson によるもの) が役立つかもしれません。

于 2009-07-22T17:50:13.357 に答える
0

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/と、コードをプロファイリングすることで速度を確認できます。

于 2009-07-22T16:42:37.330 に答える