MPI实现求解10的八次方内素数的个数(版本一)
使用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的八次方内素数的个数(版本一)相关推荐
- 统计素数并求和 (20 分)本题要求统计给定整数M和N区间内素数的个数并对它们求和。
本题要求统计给定整数M和N区间内素数的个数并对它们求和. 输入格式: 输入在一行中给出两个正整数M和N(1≤M≤N≤500). 输出格式: 在一行中顺序输出M和N区间内素数的个数以及它们的和,数字间以 ...
- 要求统计给定整数M和N区间内素数的个数,并对所有素数求和。
题目内容: 要求统计给定整数M和N区间内素数的个数,并对所有素数求和. 其中两数必须满足条件: . 如果输入的M和N不能满足以上条件,则提示"输入数据错误". 输入格式: 在一行中 ...
- 本题要求统计给定整数M和N区间内素数的个数并对它们求和。
本题要求统计给定整数M和N区间内素数的个数并对它们求和. 输入格式: 输入在一行中给出两个正整数M和N(1≤M≤N≤500). 输出格式: 在一行中顺序输出M和N区间内素数的个数以及它们的和,数字间以 ...
- 求解10的75次方问题
对于求一个数的高次方,最简单的方法,恐怕就是循环一定的次数,累乘.但是这样的效率太低.下面我提供一个高效的算法.来自左程云<程序员代码面试指南>. 就拿10的75次方举例: 1.75的二进 ...
- Python实验项目1例:使用进程池统计指定范围内素数的个数
本周赠书活动:董付国老师Python系列教材赠书活动(40本) -------------------------------- 适用专业: 适用于计算机.网络工程.软件工程等相关专业,其他专业选做. ...
- 区间内素数的个数(也要用到埃氏算法)
题目大意:给定正整数a和b,请问区间[a,b)内有多少个素数 限制条件:a<b<=10^12 b-a<=10^6 样例: 22 37 3 22801763489 2280178 ...
- 数字基本单位及2或10的幂次方
次方 值(2的幂次方) 备注 数字单位 值(10的幂次方) 1 2 个 2 4 十 3 8 百 4 16 千 5 32 万 10的四次方 6 64 十万 7 128 百万 8 256 千万 9 512 ...
- 10亿内素数个数及总和
10亿内 素数总个数:50847534 总和:24739512092254535
- 【模板小程序】求M~N范围内的质数个数
1 /* 2 本程序说明: 3 4 [编程题] 求素数 5 时间限制:2秒 6 空间限制:32768K 7 输入M.N,1 < M < N < 1000000,求区间[M,N]内的所 ...
最新文章
- java xml文件内容替换_java读取xml文件并转换成对象,并进行修改
- 我的个人网站更新了!
- 面试题目_经典面试题目「回溯算法」解数独
- Docker shipyard 试用
- aspen变压吸附塔_空压机科普:吸附式干燥机的结构和原理
- 怎样在PropertySheet中添加按钮
- java.net.ConnectException: Connection refused: connect
- 随笔小杂记(六)——tqdm进度条显示出现多余行
- matlab设计单神经元系统框图,单神经元自适应系统
- 【转载】偏最小二乘法回归(Partial Least Squares Regression)
- Java——删除文件
- Java面试宝典大集锦
- 科创板设立 币圈走向几何?
- 计算机禁止安装游戏,win7系统禁用自动安装游戏应用的详细教程
- 基于c语言的串口通讯,基于C语言的RS232串行接口通信设计与实现
- selenium设置文件下载路径
- GH4199变形合金
- html中画分割线的代码,各种分割线Html代码
- css实现奥运五环(立体)
- Python编写csdn刷博客数量软件