使用MPI计算素数个数

算法实现所使用的方法:


当所要计算的个数达到10的8次方,甚至更多时,一台机器很难胜任这份工作。
使用MPI分布式并行计算可以实现这个目标,原来一个人干的事情现在让很多个人来干,这听上去是一个很美妙的事情。
但是俗话说一个和尚挑水喝,两个和尚抬水喝,三个和尚没水喝。
程序也是如此,使用MPI实现多进程来进行计算,虽然有很多的好处,但是编程的复杂性也提升了不少。

版本一(从2到n给每个进程分配一定的任务来进行计算)

让一个进程来负责协调分配工作,其余的进程听其指挥

使用:

   low_value = 2 + id * (n - 1) / p;high_value = 1 + (id + 1) * (n - 1) / p;size = high_value - low_value + 1;

来确定每一个进程所分配的最大数和最小数,size来记录本进程所计算的大小。

计算出每一个进程中第一个可以被进程0传过来的素数整除的元素的局部索引,记录与first中。

 if (prime * prime > low_value)first = prime * prime - low_value;else {if (!(low_value % prime)) first = 0;else first = prime - (low_value % prime);}

整体:

#include "mpi.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>#define MIN(a, b)  ((a)<(b)?(a):(b))int main(int argc, char *argv[]) {unsigned long int count;        /* Local prime count */double elapsed_time; /* Parallel execution time */unsigned long int first;        /* Index of first multiple */unsigned long int global_count = 0; /* Global prime count */unsigned long long int high_value;   /* Highest value on this proc */unsigned long int i;int id;           /* Process ID number */unsigned long int index;        /* Index of current prime */unsigned long long int low_value;    /* Lowest value on this proc */char *marked;       /* Portion of 2,...,'n' */unsigned long long int n;            /* Sieving from 2, ..., 'n' */int p;            /* Number of processes */unsigned long int proc0_size;   /* Size of proc 0's subarray */unsigned long int prime;        /* Current prime */unsigned long int size;         /* Elements in 'marked' */MPI_Init(&argc, &argv);/* Start the timer */MPI_Comm_rank(MPI_COMM_WORLD, &id);   //获取进程idMPI_Comm_size(MPI_COMM_WORLD, &p);  //获取进程数量MPI_Barrier(MPI_COMM_WORLD);        //进行同步elapsed_time = -MPI_Wtime();if (argc != 2) {if (!id) printf("Command line: %s <m>\n", argv[0]);MPI_Finalize();exit(1);}n = atoll(argv[1]);     //获取要计算的数/* Figure out this process's share of the array, aswell as the integers represented by the first andlast array elements 计算这个进程在数组中的份额,以及第一个和最后一个数组元素表示的整数*//*********originalSoution*******/low_value = 2 + id * (n - 1) / p;high_value = 1 + (id + 1) * (n - 1) / p;size = high_value - low_value + 1;/* Bail out if all the primes used for sieving arenot all held by process 0 如果用于筛选的所有质数不都由进程0持有,则退出*/proc0_size = (n - 1) / p;if ((2 + proc0_size) < (int) sqrt((double) n)) {if (!id) printf("Too many processes\n");MPI_Finalize();exit(1);}/* Allocate this process's share of the array.分配此进程在数组中的份额 */marked = (char *) malloc(size);if (marked == NULL) {printf("Cannot allocate enough memory\n");MPI_Finalize();exit(1);}for (i = 0; i < size; i++) marked[i] = 0;if (!id) index = 0;            // !id----->只有0号进程才会执行。prime = 2;do {if (prime * prime > low_value)first = prime * prime - low_value;else {if (!(low_value % prime)) first = 0;else first = prime - (low_value % prime);       // 此处在求局部first(数组中第一个可以被prime整除的数)的时候非常巧妙}for (i = first; i < size; i += prime) marked[i] = 1;     // 将可以被整除的数标记起来if (!id) {while (marked[++index]);prime = index + 2;}if (p > 1) MPI_Bcast(&prime, 1, MPI_INT, 0, MPI_COMM_WORLD); // 广播,将一个进程中的数据发送到所有进程} while (prime * prime <= n);count = 0;for (i = 0; i < size; i++)if (!marked[i]) count++;    // 统计单个进程中素数的个数,看有多少个0if (p > 1)MPI_Reduce(&count, &global_count, 1, MPI_INT, MPI_SUM,0, MPI_COMM_WORLD);  // 规约,集合通信,由进程0来计算全局的count/* Stop the timer */elapsed_time += MPI_Wtime();/* Print the results */if (!id) {printf("The total number of prime: %ld, total time: %10.6f, total node %d\n", global_count, elapsed_time, p);}MPI_Finalize();return 0;}

虽然知道所有的偶数(除2以外)都不是素数,但是程序还是对所有的偶数都进行了计算,下一个版本将进行优化(不计算偶数)。

本地虚拟机的一个执行:

输出:(使用了四个核心计算10的八次方)

>>>
0:2-25000000
1:25000001-50000000
2:50000001-75000000
3:75000001-100000000
1:count 1435207
0:count 1565927
2:count 1393170
3:count 1367151
The total number of prime: 5761455, total time:   2.107253, total node 4

MPI实现求解10的八次方内素数的个数(版本一)相关推荐

  1. 统计素数并求和 (20 分)本题要求统计给定整数M和N区间内素数的个数并对它们求和。

    本题要求统计给定整数M和N区间内素数的个数并对它们求和. 输入格式: 输入在一行中给出两个正整数M和N(1≤M≤N≤500). 输出格式: 在一行中顺序输出M和N区间内素数的个数以及它们的和,数字间以 ...

  2. 要求统计给定整数M和N区间内素数的个数,并对所有素数求和。

    题目内容: 要求统计给定整数M和N区间内素数的个数,并对所有素数求和. 其中两数必须满足条件: . 如果输入的M和N不能满足以上条件,则提示"输入数据错误". 输入格式: 在一行中 ...

  3. 本题要求统计给定整数M和N区间内素数的个数并对它们求和。

    本题要求统计给定整数M和N区间内素数的个数并对它们求和. 输入格式: 输入在一行中给出两个正整数M和N(1≤M≤N≤500). 输出格式: 在一行中顺序输出M和N区间内素数的个数以及它们的和,数字间以 ...

  4. 求解10的75次方问题

    对于求一个数的高次方,最简单的方法,恐怕就是循环一定的次数,累乘.但是这样的效率太低.下面我提供一个高效的算法.来自左程云<程序员代码面试指南>. 就拿10的75次方举例: 1.75的二进 ...

  5. Python实验项目1例:使用进程池统计指定范围内素数的个数

    本周赠书活动:董付国老师Python系列教材赠书活动(40本) -------------------------------- 适用专业: 适用于计算机.网络工程.软件工程等相关专业,其他专业选做. ...

  6. 区间内素数的个数(也要用到埃氏算法)

    题目大意:给定正整数a和b,请问区间[a,b)内有多少个素数 限制条件:a<b<=10^12    b-a<=10^6 样例: 22 37 3 22801763489 2280178 ...

  7. 数字基本单位及2或10的幂次方

    次方 值(2的幂次方) 备注 数字单位 值(10的幂次方) 1 2 个 2 4 十 3 8 百 4 16 千 5 32 万 10的四次方 6 64 十万 7 128 百万 8 256 千万 9 512 ...

  8. 10亿内素数个数及总和

    10亿内 素数总个数:50847534  总和:24739512092254535 

  9. 【模板小程序】求M~N范围内的质数个数

    1 /* 2 本程序说明: 3 4 [编程题] 求素数 5 时间限制:2秒 6 空间限制:32768K 7 输入M.N,1 < M < N < 1000000,求区间[M,N]内的所 ...

最新文章

  1. java xml文件内容替换_java读取xml文件并转换成对象,并进行修改
  2. 我的个人网站更新了!
  3. 面试题目_经典面试题目「回溯算法」解数独
  4. Docker shipyard 试用
  5. aspen变压吸附塔_空压机科普:吸附式干燥机的结构和原理
  6. 怎样在PropertySheet中添加按钮
  7. java.net.ConnectException: Connection refused: connect
  8. 随笔小杂记(六)——tqdm进度条显示出现多余行
  9. matlab设计单神经元系统框图,单神经元自适应系统
  10. 【转载】偏最小二乘法回归(Partial Least Squares Regression)
  11. Java——删除文件
  12. Java面试宝典大集锦
  13. 科创板设立 币圈走向几何?
  14. 计算机禁止安装游戏,win7系统禁用自动安装游戏应用的详细教程
  15. 基于c语言的串口通讯,基于C语言的RS232串行接口通信设计与实现
  16. selenium设置文件下载路径
  17. GH4199变形合金
  18. html中画分割线的代码,各种分割线Html代码
  19. css实现奥运五环(立体)
  20. Python编写csdn刷博客数量软件

热门文章

  1. matlab s-function找不到
  2. 雷风恒:慎终如始;天山遁:大雁南飞
  3. 计算机ip地址在哪找,如何查ip地址,电脑ip地址在哪看
  4. 请查收 | 2022 阿里妈妈技术文章回顾
  5. 执行多个window.onload匿名函数的方法
  6. Javase尚硅谷笔记
  7. mysql 中 一个汉字吗_MySQL 中一个汉字占多少存储?
  8. C语言基于easyx的打字训练软件。
  9. 常用照片尺寸和纸张尺寸参考
  10. 谷粒商城项目学-分布式基础