Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用#pragma omp进行硬并行以查找第n个素数_C_Multithreading_Parallel Processing_Openmp_Primes - Fatal编程技术网

C 使用#pragma omp进行硬并行以查找第n个素数

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]

这个问题的目的是能够得到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);
}
#包括
#包括
#定义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好的,所以你改变了每段的算法,你仍然需要只通过范围内最高值平方根以下的素数进行测试。