2013-04-07 7 views
5

Ich muss in der Lage sein, zu speichern/Last-Zustand dieser Schub Zufallsgenerator:schnellere Alternative als Streams mit zufällig speichern steigern Generatorzustand

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

ich es auf diese Weise:

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

Das Problem ist, dass dies unglaublich langsam ist, gibt es keine alternative Möglichkeit, es zu speichern? (Oder greifen Sie auf die Zufallsgeneratordaten im nativen Format zu). Dieser Code ist in unserer RandomGenerator-Klasse gekapselt, so dass es ein wenig unangenehm sein kann.

+0

Dieser Schreibvorgang dauert auf meinem 2,26 GHz Mac mini etwa 0,13 Millisekunden. Wie schnell muss es sein? – rhashimoto

+4

Ich weiß nicht, 293800 CPU-Zyklen scheint wie eine lange Zeit! – Yakk

+0

Es scheint, der einzige Weg, den Staat zu retten und wiederherzustellen, ist durch einen Strom. Um die Leistung zu verbessern, können Sie einen eigenen benutzerdefinierten Stream schreiben (von "std :: streambuf" erben) und in boost :: iostreams einlesen. –

Antwort

1

Ein paar Ansätze, die beide ziemlich hacky:

  1. einfach das rohe Bytes greift etwas mit wie:

    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); 
    

    Dies funktioniert gut für In-Memory-Speicher und Laden, aber die genauen Das Format wird natürlich Compiler-und-Architektur-abhängig sein, so dass es nicht funktioniert, wenn Sie portable Persistenz benötigen. Für zusätzliche Vorsichtspunkte könnten Sie eine static_assert für etwas wie is_trivially_copyable einwerfen, um gegen (unwahrscheinliche) zukünftige Änderungen an mt19937 zu schützen.

  2. die Bedingungen der Boost-Lizenz Unter der Voraussetzung akzeptabel sind (sie sind wahrscheinlich), um Ihre eigene Kopie von der Boost-mersenne_twister Vorlage machen und es zwicken einen Zeiger auf den Zustand Array und einen Verweis auf den Array-Index zu akzeptieren. Dann ist der Zustand völlig außerhalb des Motors, und Sie können es verwalten, wie Sie wollen.

übrigens, wenn dies eine sehr häufige Operation ist und Sie nicht MT19937 die uber-hochdimensionalen Einheitlichkeit benötigen, könnten Sie ein different engine mit kleineren staatlichen Anforderungen in Betracht ziehen, wie taus88.

+0

Rechts, 2^19937-1 Länge Zyklus ist viel mehr als wir brauchen, und die Taus88 hat 200 mal kleinere Größe, also werde ich es versuchen :) – kovarex

Verwandte Themen