Frage

Ich habe mit diesem ganzen Tag gekämpft, ich versuche, einen Zufallszahlengenerator für Threads in meinem CUDA-Code zu erhalten. Ich habe durch alle Foren geschaut und ja dieses Thema kommt ein gutes Stück, aber ich habe versucht, verbrachte Stunden alle möglichen Codes ohne Erfolg zu entwirren. Wenn jemand eine einfachen Methode kennt, wahrscheinlich ein Gerät Kernel, der zu den Erträgen einen zufälligen Schwimmer zwischen 0 und 1 bezeichnet werden kann, oder eine ganze Zahl, die ich verändern kann wäre ich sehr dankbar.

Noch einmal, ich hoffe, dass die Zufallszahl in dem Kernel zu verwenden, so wie rand () zum Beispiel.

Vielen Dank im Voraus

War es hilfreich?

Lösung

Ich bin nicht sicher, ich verstehe, warum Sie etwas Besonderes brauchen. Alle traditionellen PRNG sollte Hafen mehr oder weniger direkt. Ein lineare Kongruenz sollte gut funktionieren. Haben Sie einige besondere Eigenschaften haben Sie zu etablieren sind versuchen?

Andere Tipps

Für alle Interessierten, können Sie es jetzt über cuRAND .

ich denke, jede Diskussion über diese Frage Zenna der ursprüngliche Anfrage beantworten muss, und das ist für eine Thread-Ebene Umsetzung. Spezifisch a Gerätefunktion , die von innerhalb eines Kernel aufgerufen werden kann oder Gewinde . Sorry, wenn ich die „in bold“ Phrasen overdid aber ich glaube wirklich die Antworten adressieren bisher nicht ganz das, was hier gesucht wird.

Die cuRAND Bibliothek ist die beste Wahl. Ich schätze, dass die Menschen das Rad neu erfinden wollen, sind (es macht man schätzen und richtig 3rd-Party-Bibliotheken), aber hohe Leistung hohe Qualität Zahlengeneratoren sind reichlich vorhanden und gut getestet. Die besten Informationen, die ich empfehlen kann, ist auf die Dokumentation der GSL-Bibliothek auf den verschiedenen Generatoren hier: http://www.gnu.org/software/gsl/manual/html_node/Random-number-generator-algorithms.html

Für jeden ernsthaften Code ist es am besten, eine der wichtigsten Algorithmen zu verwenden, die Mathematiker / Computer-Wissenschaftler in den Boden haben immer und immer wieder für eine systemische Schwächen suchen. Die „Mersenne Twister“ ist etwas, mit einer Periode (Wiederholungsschleife) in der Größenordnung von 10 ^ 6000 (MT19997 Algorithmus bedeutet „Mersenne Twister 2 ^ 19997“), die speziell angepasst ist für Nvidia innerhalb Gewinde der an einer Thread-Ebene zu verwenden, gleiche warp Verwendung Thread-ID-Anrufe als Samen. Siehe Papier hier: http: / /developer.download.nvidia.com/compute/cuda/2_2/sdk/website/projects/MersenneTwister/doc/MersenneTwister.pdf . Ich arbeite eigentlich somehting mit dieser Bibliothek zu implementieren und wenn ich es bekommen richtig funktioniert, ich werde meinen Code schreiben. Nvidia hat einige Beispiele an ihrer Dokumentation Website für den aktuellen CUDA-Toolkit.

. HINWEIS: Nur für das Protokoll ich arbeite nicht für Nvidia, aber ich werde ihre Dokumentation und Abstraktion Design für CUDA zugeben, ist etwas, das ich bisher mit beeindruckt


Je nach Anwendung sollten Sie vorsichtig sein LCGs verwenden, ohne zu prüfen, ob die Ströme (ein Strom pro Thread) überlappen. Sie könnten einen Leapfrog mit LCG implementieren, aber dann würden Sie einen ausreichend langen Zeitraum LCG haben müssen, um sicherzustellen, dass die Sequenz wiederholt sich nicht.

Ein Beispiel leapfrog könnte sein:

template <typename ValueType>
__device__ void leapfrog(unsigned long &a, unsigned long &c, int leap)
{
    unsigned long an = a;
    for (int i = 1 ; i < leap ; i++)
        an *= a;
    c = c * ((an - 1) / (a - 1));
    a = an;
}

template <typename ValueType>
__device__ ValueType quickrand(unsigned long &seed, const unsigned long a, const unsigned long c)
{
    seed = seed * a;
    return seed;
}

template <typename ValueType>
__global__ void mykernel(
    unsigned long *d_seeds)
{
    // RNG parameters
    unsigned long a = 1664525L;
    unsigned long c = 1013904223L;
    unsigned long ainit = a;
    unsigned long cinit = c;
    unsigned long seed;

    // Generate local seed
    seed = d_seeds[bid];
    leapfrog<ValueType>(ainit, cinit, tid);
    quickrand<ValueType>(seed, ainit, cinit);
    leapfrog<ValueType>(a, c, blockDim.x);

    ...
}

Aber dann ist die Zeit des Generators ist wahrscheinlich nicht ausreichend in den meisten Fällen.

Um ehrlich zu sein, würde ich sehe einen Dritten Bibliothek wie NAG bei Verwendung von . Es gibt einige Batch-Generatoren im SDK auch, aber das ist wahrscheinlich nicht das, was Sie suchen in diesem Fall.

Bearbeiten

Da diese gerade aufge gestimmt, ich meine, es ist erwähnenswert, dass die Aktualisierung cuRAND zu erwähnen, wie durch neuere Antworten auf diese Frage erwähnt, ist verfügbar und bietet eine Reihe von Generatoren und Verteilungen. Das ist definitiv der einfachste Ort zu starten.

Der beste Weg, dies ist Ihre eigene Gerät Funktion zu schreiben, hier ist das ein

void RNG()
{   
    unsigned int m_w = 150;
    unsigned int m_z = 40;

    for(int i=0; i < 100; i++)
    {
        m_z = 36969 * (m_z & 65535) + (m_z >> 16);
        m_w = 18000 * (m_w & 65535) + (m_w >> 16);

        cout <<(m_z << 16) + m_w << endl;  /* 32-bit result */
    }
}

Es gebe Ihnen 100 Zufallszahl mit 32-Bit-Ergebnis.

Wenn Sie einige Zufallszahl zwischen 1 und 1000 wollen, können Sie nehmen auch die result%1000, entweder am Ort des Verbrauchs oder am Point-of-Generation:

((m_z << 16) + m_w)%1000

Ändern M_W und M_Z Startwerte (im Beispiel 150 und 40) ermöglichen es Ihnen, ein anderen Ergebnisse jedes Mal zu bekommen. Sie können threadIdx.x als einer von ihnen verwenden, die Sie jedes Mal verschiedene Pseudo-Zufalls-Serie geben sollte.

wollte ich hinzufügen, dass es funktioniert 2 mal schneller als rand () Funktion und funktioniert gut;)

Es gibt ein MDGPU Paket (GPL), die eine Implementierung des GNU rand48 enthält () Funktion für CUDA hier .

Ich fand es (ganz leicht, mit Google, die ich nehme an, Sie versucht :-) auf den NVidia-Foren hier .

Ich habe keinen guten parallel Zahlengenerator für CUDA gefunden, jedoch habe ich basierend auf dem akademische Forschung hier einen parallelen Zufallszahlengenerator finden: http://sprng.cs.fsu.edu/

Sie könnten versuchen, Mersenne-Twister für GPUs

Es basiert auf SIMD-orientierte Schnellen Mersenne-Twister (SFMT), der ein ziemlich schneller und zuverlässiger Zufallszahlengenerator ist. Es geht Marsaglias DIEHARD Tests für Zufallszahlengeneratoren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top