C と Java で Eratosthene のふるいアルゴリズムを開発しましたが、いくつかの問題に遭遇しました。
素数の配列を管理するために、C では char の配列 (要素ごとに 8 ビット) を使用し、Java では boolean の配列 (要素ごとに 8 ビット) を使用しました。
N=1,000,000,000 まで素数を計算しようとすると (N 要素の配列があるため)、Java アプリケーションはうまく機能します (ヒープ サイズを 1.5GB に拡張しました)。C アプリケーションで同じことをしようとすると、メモリが不足します (制限は N=680,000,000 です)。
同じ N=500,000,000 で両方のアプリケーションを実行すると、確認したところ、両方とも約 512MB の RAM を占有しているため、Java アプリケーションが N=1,000,000,000 で正常に動作する場合、C アプリケーションがすぐに実行に失敗する理由がわかりません。
私が知らないJavaの「-Xmx1536m」のようなCの「オプション」はありますか?
4GB の RAM があり、Windows 7 64 ビットを使用しています。sizeof(size_t) の値も確認したところ 32 だったので、4GB のメモリを適切に割り当てることができると思います。
編集: Cygwin の 64 ビット版を試してみたところ、N=1,000,000,000 で正常に動作するようになりました。これには理由がありますか?1GBのメモリには64ビットではなく32ビットが「必要」だと思います...
ここにアプリケーションのソースがあります。
ジャワ:
int N = 1000000000;
int m;
boolean[] isPrime = new boolean[N + 1];
for (int i = 2; i <= N; i++) {
isPrime[i] = true;
}
for (int i = 2; i*i <= N; i++) {
if (isPrime[i]) {
for (int j = i; (m = i*j) <= N; j++) {
isPrime[m] = false;
}
}
}
子:
int N = 1000000000;
int i, j, m;
char *isPrime;
isPrime = malloc(sizeof(char)*(N+1));
for (i = 2; i <= N; i++) {
isPrime[i] = 1;
}
for (i = 2; i*i <= N; i++) {
if (isPrime[i]) {
for (j = i; (m = i*j) <= N; j++) {
isPrime[m] = 0;
}
}
}