この問題の目的は、2.000.000 番目の素数を取得し、2.000.000 番目の素数がどれであるかを判別できるようにすることです。
次のコードから始めます。
#include <stdlib.h>
#include <stdio.h>
#define N 2000000
int p[N];
main(int na,char* arg[])
{
int i;
int pp,num;
printf("Number of primes to find: %d\n",N);
p[0] = 2;
p[1] = 3;
pp = 2;
num = 5;
while (pp < N)
{
for (i=1; p[i]*p[i] <= num ;i++)
if (num % p[i] == 0) break;
if (p[i]*p[i] > num) p[pp++]=num;
num += 2;
}
printf("The %d prime is: %d\n",N,p[N-1]);
exit(0);
}
ここで、プラグマ omp を介してこのプロセスをスレッド化するよう求められます。これは私がこれまでに行ったことです:
#include <stdlib.h>
#include <stdio.h>
#define N 2000000
#define D 1415
int p[N];
main(int na,char* arg[])
{
int i,j;
int pp,num;
printf("Number of primes to find: %d\n",N);
p[0] = 2;
p[1] = 3;
pp = 2;
num = 5;
while (pp < D)
{
for (i=1; p[i]*p[i] <= num ;i++)
if (num % p[i] == 0) break;
if (p[i]*p[i] > num) p[pp++]=num;
num += 2;
}
int success = 0;
int t_num;
int temp_num = num;
int total = pp;
#pragma omp parallel num_threads(4) private(j, t_num, num, success)
{
t_num = omp_get_thread_num();
num = temp_num + t_num*2;
#pragma omp for ordered schedule(static,4)
for(pp=D; pp<N; pp++) {
success = 0;
while(success==0) {
for (i=1; p[i]*p[i] <= num;i++) {
if (num % p[i] == 0) break;
}
if (p[i]*p[i] > num) {
p[pp] = num;
success=1;
}
num+=8;
}
}
}
//sort(p, 0, N);
printf("El %d primer es: %d\n",N,p[N-1]);
exit(0);
}
ここで、私の「部分的な」解決策、つまり私の問題について説明しましょう。
最初の D 素数はシーケンシャル コードで取得されるため、大量の数の割り切れる可能性を確認できます。
各スレッドは素数の対角線を実行するため、スレッド間に依存関係がなく、同期の必要がありません。ただし、このアプローチには次の問題があります。
- あるスレッドが別のスレッドよりも多くの素数を生成する場合があります
- 問題 1. の直接的な結果として、N 個の素数が生成されますが、それらは順序付けられません。そのため、素数カウンター 'pp' が 'N' に達すると、最後の素数は 2.000.000 番目の素数ではなく、より高度なプライム。
- また、2.000.000 個の素数を生成するまでに、実際の 2.000.000 番目の素数に到達できるスレッドには、それを素数配列 'p' に配置するだけの十分な時間がない可能性もあります。
そして、質問/ジレンマは次のとおりです。
2.000.000 番目の素数がいつ生成されるかを知るにはどうすればよいですか?
ヒント: 10.000 候補の素数をバッチ処理するように言われました。その後、何かわからないことが起こったときに、10.000 の候補の最後のバッチに 2.000.000 番目の素数が含まれていることがわかり、クイックソートで並べ替えることができます。
これは本当に厳しいエクササイズであり、数日間ノンストップで試してみました.