2013-04-07 10 views
5

muszę być w stanie uratować/stan obciążenia tego doładowania generatora:Szybsza alternatywa niż przy użyciu strumieni zapisać zwiększyć losowy generator stan

boost::variate_generator<boost::mt19937, boost::random::uniform_real_distribution<> > generator; 

zrobić to w ten sposób:

std::ostringstream content; 
content << this->generator.engine(); 

Problem polega na tym, że jest to niesamowicie powolne, czy nie ma jakiegoś alternatywnego sposobu przechowywania? (Lub uzyskać dostęp do danych generatora losowego w formacie macierzystym). Ten kod jest zamknięty w naszej klasie RandomGenerator, więc może być trochę nieprzyjemny.

+0

Ten zapis zajmuje około 0,13 milisekund na moim komputerze Mac mini 2,26 GHz. Jak szybko musi być? – rhashimoto

+4

I dunno, 293800 Cykle procesora wydają się być od dawna! – Yakk

+0

Wygląda na to, że jedynym sposobem na zapisanie i przywrócenie stanu jest strumień. Aby zwiększyć wydajność, możesz napisać swój własny strumień (dziedziczą z 'std :: streambuf') i przeczytać go lub wyszukać boost :: iostreams. –

Odpowiedz

1

Kilka podejść, zarówno dość hacky:

  1. Wystarczy chwycić surowe bajty za pomocą czegoś takiego:

    typedef typename std::aligned_storage<sizeof(boost::mt19937)>::type mt19937_storage; 
    mt19937_storage storage; 
    std::memcpy(&storage, &generator, sizeof(generator)); 
    //... 
    generator.engine() = *reinterpret_cast<boost::mt19937*>(storage); 
    

    Działa to dobrze w pamięci zapisywania i ładowania, ale dokładny format będzie oczywiście zależny od kompilatora i architektury, więc nie będzie działać, jeśli potrzebujesz przenośnej trwałości. Aby uzyskać dodatkowe punkty ostrożności, możesz rzucić static_assert coś podobnego do is_trivially_copyable, aby ochronić przed (mało prawdopodobne) przyszłymi zmianami na mt19937.

  2. Zakładając, że warunki licencji Boost są akceptowalne (prawdopodobnie są), zrób własną kopię szablonu Boost'a o numerze mersenne_twister i dostosuj go, aby zaakceptować wskaźnik do tablicy stanów i odwołanie do indeksu tablicy. Wtedy stan jest całkowicie niezależny od silnika i możesz nim zarządzać w dowolny sposób.

Nawiasem mówiąc, jeśli jest to bardzo częsta operacja i nie trzeba uber-high-dimensional jednolitość MT19937 jest, można rozważyć użycie different engine z mniejszymi wymaganiami państwowymi, takimi jak taus88.

+0

Długość cyklu 2^19937-1 jest znacznie większa niż potrzebujemy, a taus88 ma 200 razy mniejszy rozmiar, więc spróbuję :) – kovarex

Powiązane problemy