此問題的目標是能夠獲得2.000.000個第一素數並能夠確定哪個是第2000000個素數。使用#pragma omp進行硬性並行化以找到第N個素數
我們從這個代碼開始:
#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'時,最後一個素數不是第2000000個素數,這是更高級的素數。
- 它也可能是當它產生2.000.000個素數的時候,能夠達到真正的2.000.000th素數的線程可能沒有足夠的時間來把它放在素數組'p'上。
而問題/困境是:
我如何能夠產生2.000.000th素時,知道嗎?
提示: 有人告訴我應該批量(比方說)10.000候選人素數。然後當我不知道發生的事情時,我會知道最後一批10.000個候選人包含2000萬個素數,我可以用快速排序對它進行排序。
我希望我明確自己,這是真正的鍛鍊,我只是試了幾天不停。
是的!第一種方法似乎是最容易實現的。我會從第一個開始,然後如果我覺得我還沒有厭倦這個問題,我可能會執行第二個。因爲快速排列的2M位置可能是加速的痛苦。非常感謝你。 –