C 使用#pragma omp进行硬并行以查找第n个素数
这个问题的目的是能够得到2.000.000个第一个素数,并能够判断出第2.000.000个素数是什么 我们从以下代码开始:C 使用#pragma omp进行硬并行以查找第n个素数,c,multithreading,parallel-processing,openmp,primes,C,Multithreading,Parallel Processing,Openmp,Primes,这个问题的目的是能够得到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]
#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);
}
#包括
#包括
#定义N 2000000
int p[N];
main(int-na,char*arg[])
{
int i;
int-pp,num;
printf(“要查找的素数:%d\n”,n);
p[0]=2;
p[1]=3;
pp=2;
num=5;
while(pp
现在,我们被要求通过via pragma 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);
}
#包括
#包括
#定义N 2000000
#定义D 1415
int p[N];
main(int-na,char*arg[])
{
int i,j;
int-pp,num;
printf(“要查找的素数:%d\n”,n);
p[0]=2;
p[1]=3;
pp=2;
num=5;
而(pp 对于(pp=D;pp我可以想到两种方法
一旦你有了第二百万个素数的候选者,你的线程就会继续计算低于候选者的素数,直到你没有缺少素数为止。然后你可以对素数列表进行排序,并从中获取第二百万个素数
如果您的线程正在生成连续素数块,它们应该单独维护这些块,然后这些素数块可以随后重新组装到主列表中。进行重新组装的线程可以在找到第200万个素数后终止程序
如果您只需要2000000个素数,则可以维护一个大小约为4.1MB的位数组,并为每个找到的素数在其上翻转位。无需排序。通过实施仅赔率表示方案,将位数组大小减半
分段使用,大小与sqrt(范围的顶部值)成比例(或类似的-目标是在每个分段上执行大致相同的工作量)。对于n=2000000
,n*(log n+log(log n))==34366806
,和prime[771]^2==34421689
(基于0),那么,预先计算前771个奇素数
每个工作进程在翻转位时也可以计数,因此当它们全部完成时,您将知道每个范围的计数,并且只需要扫描包含第2mn个素数的一个范围,最终找到该素数。或者让每个工作进程根据其范围维护自己的位数组-您只需保留一个,就可以使用光盘我和其他人一样
Eratosthenes筛子计数的伪代码为:
Input: an integer n > 1
Let A be an array of bool values, indexed by integers 3, 5, ... upto n,
initially all set to true.
count := floor( (n-1)/2 )
for i = 3, 5, 7, ..., while i^2 ≤ n:
if A[i] is true:
for j = i^2, i^2 + 2i, i^2 + 4i, ..., while j ≤ n:
if A[j] is true:
A[j] := false
count := count - 1
Now all 'i's such that A[i] is true are prime,
and 'count' is the total count of odd primes found.
是的!第一种方法似乎最容易实现。我将从第一种方法开始,然后如果我觉得我还不厌倦这个问题,我可以实现第二种方法。因为2米位置的快速排序可能会对加速带来痛苦。非常感谢。我很欣赏这个回答,但我们不允许更改算法。W我们必须并行化你看到的那个。但是很好的伪代码,谢谢。@ÀlexVinyals好的,所以你改变了每段的算法,你仍然需要只通过范围内最高值平方根以下的素数进行测试。