2

そのため、私はCでいくつかのアプリケーションを作成し、並列化にOpenMPを使用しています。モンテカルロ円周率推定を実装したところ、通常のrand()関数は再入可能でスレッドセーフではないことがわかりました。drand48_rオプションを使用することをお勧めします。

ここに問題があります。私のアプリケーションはLinuxで正常にコンパイルされます。Ubuntu、Fedora、CentOSですが、MacOSXではコンパイルされません。OSXでのコンパイルエラーはです。

simple.c:7:エラー:「randBuffer」のストレージサイズが不明です

簡単な例として使用されるコードは次のとおりです。

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

int main(int argc, char* argv[]) {

  double x;
  struct drand48_data randBuffer;

  srand48_r(time(NULL), &randBuffer);

  drand48_r(&randBuffer, &x);

  printf("Random number: %f\n", x);

  return EXIT_SUCCESS;
}

それについて読んだところ、manページに次のようなメモが見つかりました。

これらの関数はGNU拡張機能であり、移植性はありません。

これへのリンクは次のとおりです:http ://www.kernel.org/doc/man-pages/online/pages/man3/drand48_r.3.html

ですから、いくつか質問があります。

  1. GNU拡張機能とは何ですか?また、移植性がない理由は何ですか?
  2. スレッドセーフでもあるOSXでの乱数生成にはどのような選択肢がありますか?

さて、それはそれについてです。

この例は、gccを使用してコンパイルされています。

gcc simple.c -o simple

4

2 に答える 2

5

drand48_roverを使用するメリットはあまりありませんerand48erand48と同じタイプの乱数発生器がありますが、それとdrand48比較すると、乱数発生器の状態を関数パラメーターとして受け取るため、完全に機能します。

拡張機能は結果を所定の_r場所 (2 番目のパラメーター) に格納し、常に保証されるエラー コードを返します0。私はこれらすべてにあまり使い道がありません。私は POSIX インターフェイス (特にerand48) に固執します。

于 2012-04-04T16:14:16.403 に答える
4

の標準の再入可能関数を使用し<stdlib.h>ます。それらは単純にどこにでもある_r接尾辞より前の日付であるため、それらの名前は次のとおりです。

 #include <stdlib.h>

 double drand48(void);

 double erand48(unsigned short xsubi[3]);

 long jrand48(unsigned short xsubi[3]);

 void lcong48(unsigned short param[7]);

 long lrand48(void);

 long mrand48(void);

 long nrand48(unsigned short xsubi[3]);

 unsigned short *seed48(unsigned short seed16v[3]);

 void srand48(long seedval);

このerand48()関数は、状態としてデータ構造 (実際には、3 つの unsigned short の配列) を取ります。したがって、それをローカルに定義された構造にバンドルしてcallを作成drand48_r()することで Mac OS X 用に実装できます。または、POSIX で定義され、ほとんどの Unix システムで 1980 年代から利用可能になっているものを移植して使用することもできます。個人的には、移植性を重視しますが、どのヘッダーがそれを宣言しているかを整理することを除けば、簡単に書くことも簡単です。drand48_datadrand48_r()erand48()erand48()drand48_r()

于 2012-04-04T16:15:37.287 に答える