2009-07-22 9 views
7

До сих пор я использую C# Mersenne Twister найти здесь для генерации случайных чисел:C# Вихрь Мерсенна реализация генератора случайных целое (SFMT) монте карло моделирование

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

Я только что обнаружил SFMT который предполагается, что в два раза быстрее здесь:

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

Может ли кто-нибудь указать мне на реализацию C# SFMT?

Мои требования - генерировать целое число между (и включая) 0 и 2^20 (1048576).

Мне нужно сделать это триллионов раз в день для моделирования, работающего на 24-часовых часах, поэтому я готов провести дни, настраивая это до совершенства.

В настоящее время я подправили центр Space Вихрь Мерсенна, добавив новый метод, чтобы соответствовать моим требованиям:

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

Используя метод genrand_int32() Я хотел бы, чтобы произвести свою собственную версию, genrand_int20(), который генерирует целое число между (и включая) 0 и 2^20 для сохранения на приведенном выше смещениях и сдвиге, но я не понимаю математику. Как я могу это сделать?

Также используется uint будет быстрее, чем int, или это всего лишь номер адреса? Потому что мне нужно только до 1048576, меня беспокоит только скорость.

Кроме того, это будет работать на 2003 R2 SP2 (32bit) ящик Windows Server с .NET 2. Процессор является AMD Opteron 275 (4 ядра).

+0

20-разрядное число будет представлять собой диапазон от 0 до 2^20-1 включительно, 2^20 требуется 21 бит для представления (a 1, за которым следует 20 нулей) –

+1

Nifle: не путайте * период * генератора (который является длиной последовательности) с * интервалом *, в котором вы хотите случайные числа. – Joey

+0

@Patrick спасибо, что вы правы 2^20-1 - это то, что мне нужно, мне нужно случайным образом индексировать массив длиной 2^20. – m3ntat

ответ

5

Что вы можете сделать, это загрузить source from the link, который вы обнаружили в Code Project. Разархивируйте его, загрузите решение в Visual Studio и скомпилируйте его. Это даст вам источник, неуправляемую c dll и .lib-файл.

Вы можете P/вызывать функции в этой DLL (есть только 5 простых функций, экспортированных, из которых вам нужно всего два), или вы можете использовать эту DLL, lib и заголовочный файл SFMT для создания управляемой обертки dll, вы можете использовать в C# без P/Invoke. Я просто попробовал этот метод, и это было очень просто сделать. Не было никакого явного участия.

Вот как это сделать. После того, как вы загрузили и скомпилировали источник (вам нужен заголовок и файл lib, который создается в дополнение к dll), создайте новый проект библиотеки классов CLR CLR. Назовите это WrapSFMT или что-то в этом роде. Перейдите к свойствам проекта. В разделе C++/Precompiled Headers измените значение на «Не использовать предварительно скомпилированные заголовки». В разделе 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 находится на пути, и у вас не должно быть проблем.

+0

Я загрузил его библиотеки DLL и попытался добавить их в качестве ссылки на мой проект C#, который я получаю: --------------------------- Microsoft Visual Studio --------------------------- Ссылка на 'SFMTc.dll' не может быть добавлена. Убедитесь, что файл доступен, и что он является допустимым компонентом сборки или COM. --------------------------- ОК -------------------- -------- Любые идеи? о том, как использовать это, и называть его наиболее эффективным способом из Visual Studio – m3ntat

+0

Хорошо, что я разместил DLL в моей папке bin и получил код: [DllImport ("SFMTc.dll")] static extern UInt32 gen_rand32(); Этот звонок без ошибок, но все, что я получаю, равно 0, никогда никакого другого номера. – m3ntat

+0

Если вы хотите использовать P/Invoke, вам нужно будет вызвать две функции init_gen_rand (UInt32), инициализируя генератор семенем, а затем вы можете вызвать gen_rand32() столько, сколько хотите. (но вы, вероятно, не должны превышать период Mersenne Twister) –

0

Я действительно не вижу вашу проблему со скоростью здесь. На моей машине (Core 2 Duo T7200 @ 2 ГГц) генерирование случайного целого числа с MT19937 или MT19937-64 занимает около 20 нс (в среднем при выводе 50000 номеров). Так что это будет около 4,32 × 10 (так около 4 трлн номеров) в день. И это для одного ядра. С Java. Поэтому я думаю, вы можете ожидать, что производительность будет более чем достаточной для ваших нужд.

Чтобы ответить на ваш вопрос: я не знаю о реализации SFMT в C#, но преобразование кода C в C# должно быть довольно простым. Тем не менее, вы не набираете много, поскольку SFMT оптимизирован для SIMD, а C# в настоящее время не поддерживает это напрямую.

+0

Я рассчитал ежедневные требования к случайным номерам для этой модели для поддержки бизнеса на уровне 1 645 668 000 000. Моделирование делает много других вещей, главным образом, умножение матриц, поэтому я не могу выделить все время процессора для генерации случайных чисел, очевидно, что я хочу как можно больше свести к минимуму каждый случайный номер gen, следовательно, вопрос о Stackoverflow. – m3ntat

+1

Ну, у вас все еще есть несколько ядер и симуляции Монте-Карло, как правило, довольно параллелизуемы.Я бы сказал, что вам следует в первую очередь решить проблему и пересмотреть отдельные части решения, если они окажутся проблемой производительности. – Joey

+0

Для SFMT я не понимал, что, возможно, мой лучший подход - попробовать скомпилировать версию c здесь: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/bin/dl/ dl.cgi? SFMT: SFMT-src-1.3.3.zip, а затем использовать его из моего моделирования C# monte carlo. Я не знаком с c/C++, как скомпилировать их src и как использовать его с C#. – m3ntat

0

Есть ли причина, по которой вы не можете скомпилировать реализацию C в DLL и вызвать это из своего кода на C#?

EDIT:

Мне очень жаль, но у меня есть только очень ограниченное знание C (и действительно C#), но «Как создать DLL C» можно ответить здесь: http://www.kapilik.com/2007/09/17/how-to-create-a-simple-win32-dll-using-visual-c-2005/ и насколько быстро можно проверить путем профилирования кода.

+0

Привет, Патрик, я никогда не использовал c, не знаю, как это сделать? и использовать с C#, я, скорее всего, потеряю много выигрышей по производительности, полагая, что .net делает некоторую упаковку моих вызовов с C# в базовую DLL? – m3ntat

+0

Я бы предположил, что P/Invoke неоднократно в неконтролируемый код несут довольно тяжелые издержки производительности. – Joey

+0

Я только что обнаружил это: http://www.codeproject.com/KB/DLL/SFMT_dll.aspx?msg=3130186 Мне интересно, может ли это оказаться полезным для моей ситуации. – m3ntat

0

Возможно, this - то, что вы ищете? Существует список из нескольких вариантов реализации.

В частности, this one (от Cory Nelson) может быть полезно.

1

Вы можете найти C# реализацию SFMT (плюс другие алгоритмы ГСЧ) на ... http://rei.to/random.html страницы и исходного кода комментарии в японском языке, но вы должны быть в состоянии понять это.

Вы также можете найти Google-переведенную версию (на английском языке) страницы на ... http://translate.google.com/translate?hl=en&sl=ja&u=http://rei.to/random.html