2009-12-08 7 views
5

私はBeowulfクラスタ上でMPIと並列プログラミングしています。我々は、シミュレーテッドアニーリングのための並列アルゴリズムを書いた。それはうまく動作します。シリアルコードよりも15倍高速な実行が期待されます。しかし、異なるアーキテクチャーやオペレーティングシステムでシリアルCコードを実行しただけで、性能測定のために異なるデータセットを持つことができました。このランダム関数をコードで使用しました。我々は両方のウィンドウとubuntu LinuxでGCCを使用します。私たちは、Linuxでの実行にはかなりの時間がかかることを知りました。その理由はわかりません。誰かがこのコードをLinuxやWindowsでgccでコンパイルして説明することができますか?GCCの性能

#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; 
    } 

私はNUM_ITERATIONSの引数として100 000 000でそれを実行した場合、私は窓に比べてLinux上で20倍遅く実行を取得します。デュアルブートwin + ubuntu linuxと同じアーキテクチャのマシンでテストされています。このランダム関数は、私たちのデータで表示したいもののボトルネックなので、私たちは助けが必要です。

+0

linuxでこれをコンパイルするときにgccに渡すコマンドラインオプションと、どのオプションがウィンドウで使われていますか? –

+0

"gcc -o rand rand.c -lm" 両方のシステムで。 – Zec

+2

乱数ジェネレータがどのようなものになっても、プログラム実行ごとに** ** 1回**初期化してください。 ** ONCE ONLY!** – pmg

答えて

1

他の乱数発生器を調べることにします。実行速度と擬似ランダム性の点で、標準ライブラリのランダム関数よりも十分にテストされ、優れた性能を発揮するものが多数存在します。私は大学院のクラスで独自のRNGを実装しましたが、実動コードでは使用しません。コミュニティによって吟味されたものと一緒に行きなさい。 Random.orgは、選択したRNGをテストするのに適したリソースです。

8

Linux gccの場合、ランダム関数内のsrand(rand());の呼び出しは、98%を超える時間を占めます。

少なくともループ内にはない乱数の生成には必要ありません。あなたはすでにsrand()に電話をしています。それで十分です。

+0

私たちは常に種を交換する必要があります。 void srand(unsigned int seed); 擬似乱数ジェネレータは、シードとして渡された引数を使用して初期化されます。 srandの呼び出しで使用されるすべての異なるシード値に対して、擬似乱数ジェネレータは、それ以降のrandの呼び出しで異なる結果の連続を生成することが期待できます。 同じシードを持つ2つの異なる初期化は、擬似ランダムジェネレータに、その後の両方の場合のrand呼び出しの結果の同じ連続を生成するように指示します。 – Zec

+3

@ ZeKoU - あなたが間違っていると言っているわけではありませんが、このコードはかなり怪しいです。私はあなたが決定論的または推測可能なシーケンスを生成しているかもしれないと思いますが(確かではありません) 'srand'の中の' rand'の最初の呼び出しは常にsrandに同じ値を渡します。そこから、私は攻撃者があなたのことを再実行できると思います。私はdtrossetが正しいと信じています。さらに、代わりに 'srand(time(NULL))'を呼び出すこともできます:http://stackoverflow.com/questions/1108780/why-do-i-always-get-the-same-sequence-of-random-番号付きの –

+0

int randPrime(){return srand(rand())、rand();} ? – ima