2009-12-08 15 views
5

Ich mache parallele Programmierung mit MPI auf Beowulf Cluster. Wir haben einen parallelen Algorithmus für simuliertes Annealing geschrieben. Es funktioniert gut. Wir erwarten 15-mal schnellere Ausführung als mit seriellem Code. Wir haben jedoch einige serielle C-Codes auf verschiedenen Architekturen und Betriebssystemen ausgeführt, nur um unterschiedliche Datensätze für die Leistungsmessung zu erhalten. Wir haben diese Random-Funktion in unserem Code verwendet. Wir verwenden GCC sowohl auf Windows als auch auf Ubuntu Linux. Wir haben herausgefunden, dass die Ausführung von Linux viel länger dauert und wir wissen nicht warum. Kann jemand diesen Code auf Linux und Windows mit gcc kompilieren und versuchen, mich zu erklären.GCC Leistung

#include <stdio.h> 
    #include <stdlib.h> 
    #include <time.h> 

    int main (int argc, char** argv){ 
     double Random(); 

     int k,NUM_ITERATIONS = 10; 
     clock_t start_time = clock(); 
     NUM_ITERATIONS=atoi(argv[1]); 

     // iniciranje random generatora 
     srand(time(NULL)); 

     for(k=0; k<NUM_ITERATIONS; k++){ 
       double raa = Random(); 
     } 
     clock_t end_time = clock(); 
    printf("Time of algorithm execution: %lf seconds\n", ((double) (end_time - start_time))/CLOCKS_PER_SEC); 

    return 0; 
    } 

    // generate random number bettwen 0 and 1 
    double Random(){ 
     srand(rand()); 
     double a = rand(); 
     return a/RAND_MAX; 
    } 

Wenn ich es mit 100 000 000 als Argument für NUM_ITERATIONS auszuführen, erhalte ich 20-mal langsame Ausführung auf Linux als unter Windows. Getestet auf der Maschine mit der gleichen Architektur mit Dual Boot Win + Ubuntu Linux. Wir brauchen Hilfe, da diese Zufallsfunktion ein Flaschenhals für das ist, was wir mit unseren Daten zeigen wollen.

+0

Welche Befehlszeilenoptionen übergeben Sie an gcc, wenn Sie dies in Linux kompilieren und welche Optionen in Windows verwendet werden. –

+0

"gcc -o rand rand.c -lm" Auf beiden Systemen. – Zec

+2

Welchen Zufallsgenerator Sie auch haben, initialisieren Sie ihn ** einmal ** pro Programmlauf. ** Nur einmal! ** – pmg

Antwort

1

Ich würde andere Zufallszahlengeneratoren untersuchen. Es gibt viele, die gut getestet wurden und eine bessere Leistung zeigen als die zufälligen Standardbibliotheksfunktionen, sowohl hinsichtlich der Ausführungsgeschwindigkeit als auch hinsichtlich der Pseudozufälligkeit. Ich habe auch meinen eigenen RNG für eine Graduiertenklasse implementiert, aber ich würde es nicht im Produktionscode verwenden. Geh mit etwas, das von der Gemeinde überprüft wurde. Random.org ist eine gute Ressource zum Testen von RNG, die Sie auswählen.

8

Auf Linux gcc, der Aufruf an srand(rand()); innerhalb der Random-Funktion für mehr als 98% der Zeit.

Es wird nicht für die Generierung von Zufallszahlen benötigt, zumindest nicht innerhalb der Schleife. Sie rufen bereits srand() einmal, es ist genug.

+0

Wir müssen den Samen die ganze Zeit ändern. void srand (nicht signierter int same); Der Pseudozufallszahlengenerator wird mit dem als Seed übergebenen Argument initialisiert. Für jeden anderen Startwert, der in einem Aufruf von srand verwendet wird, kann erwartet werden, dass der Pseudozufallszahlengenerator in den nachfolgenden Aufrufen von rand eine unterschiedliche Folge von Ergebnissen generiert. Zwei verschiedene Initialisierungen mit demselben Startwert weisen den Pseudozufallsgenerator an, in beiden Fällen die gleiche Folge von Ergebnissen für die nachfolgenden Aufrufe von rand zu generieren. – Zec

+3

@ZeKoU - Ich sage nicht, dass Sie falsch liegen, aber dieser Code riecht ziemlich fischig. Ich denke (bin mir aber nicht sicher), dass Sie möglicherweise eine deterministische oder erratbare Sequenz erzeugen. Der erste Aufruf der 'rand' innerhalb der 'srand' wird immer srand mit dem gleichen Wert zu säen. Von dort denke ich, dass ein Angreifer deine könnte wieder laufen. Ich glaube dtrosset ist korrekt. Zusätzlich können Sie 'srand (time (NULL))' stattdessen aufrufen: http://stackoverflow.com/questions/1108780/why-do-i-always-get-the-same-sequence-of-random- numbers-with-rand –

+0

ist Ihnen nicht aufgefallen, dass int randPrime() {zurück srand (rand()), rand();} ? – ima