利用 MPI 求素数个数
实验题目
- 实验题目
利用 MPI,OpenMP 编写简单的程序,测试并行计算系统性能 - 实验内容
两道题,每道题需要使用 MPI 和 OpenMP 分别实现:- 求素数个数
- 实验描述:
给定正整数 n,编写程序计算出所有小于等于 n 的素数的个数 - 实验要求:
需要测定 n=1,000;10,000;100,000;500,000(逗号仅为清晰考虑)时程序运行的时间
- 实验描述:
- 求 Pi 值
- 实验描述:
给定迭代次数 n,编写程序计算 Pi 的值 - 实验要求:
算法必须使用近似公式求解。需要测定 n=1,000;10,000;50,000;100,000(逗号仅为清晰考虑)时程序运行的时间
- 实验描述:
- 求素数个数
实验环境
操作系统 | 编译器 | 硬件配置 |
---|---|---|
Ubuntu 16.04 | gcc mpicc | 双核 4G内存 |
算法设计与分析
求素数个数
检测一个整数a是否为素数:如果从2到a\sqrt{a}a均无法整除a,那么a即为素数。由于除2以外的所有偶数都不是素数,所以只需要检测1~n中所有的奇数(这里把1当作素数,把2当作非素数,虽然有违常理,但对求素数个数没有影响)。
求 Pi 值
核心代码
求素数个数 MPI
初始化MPI环境,获取并行环境参数(总线程数、本地进程编号等)。
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
从0号进程获取输入n,并将其广播出去。
if(myid == 0){printf("输入n:");scanf("%d",&n);startwtime = MPI_Wtime();
}
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); //将n值广播出去
并行计算,然后将结果进行规约。pi即为最终结果
sum = 0;
for(int i = myid*2+1; i <= n; i += numprocs*2){sum += isPrime(i);
}
mypi = sum;
MPI_Reduce(&mypi, &pi, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); //规约
求素数个数 OpenMP
openMP相对比较简单,omp_set_num_threads()设置线程数,#pragma omp parallel for语句开启并行化,reduction(+:sum)表示各线程的运行结果sum最终要进行加法运算。
omp_set_num_threads(2);
#pragma omp parallel for reduction(+:sum)
for(int i = 1; i <= n; i += 2){sum += isPrime(i);
}
求 Pi 值 MPI
初始化MPI环境,获取并行环境参数(总线程数、本地进程编号等)。
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
从0号进程获取输入n,并将其广播出去。
if(myid == 0){printf("输入n:");scanf("%d",&n);startwtime = MPI_Wtime();
}
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); //将n值广播出去
并行计算,然后将结果进行规约。pi即为最终结果
sum = 0;
for(int i = myid; i <= n; i += numprocs){sum += (i % 2 == 0 ? 4.0 : (-4.0)) / (2 * i + 1);
}
mypi = sum;
MPI_Reduce(&mypi, &pi, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); //规约
求 Pi 值 OpenMP
openMP相对比较简单,omp_set_num_threads()设置线程数,#pragma omp parallel for语句开启并行化,reduction(+:sum)表示各线程的运行结果sum最终要进行加法运算。
omp_set_num_threads(2);
#pragma omp parallel for reduction(+:sum)
for(int i = 0; i <= n; i++){sum += (i % 2 == 0 ? 4.0 : (-4.0)) / (2 * i + 1);
}
实验结果
规模/线程数 | 1 | 2 | 4 | 8 |
---|---|---|---|---|
1000 | 0.000075 | 0.020078 | 0.035705 | 0.063428 |
10000 | 0.000652 | 0.017054 | 0.038764 | 0.070721 |
100000 | 0.029157 | 0.039937 | 0.057087 | 0.071655 |
1000000 | 0.404605 | 0.334772 | 0.280256 | 0.238929 |
5000000 | 3.335149 | 2.538442 | 2.142986 | 2.016233 |
规模/线程数 | 1 | 2 | 4 | 8 |
---|---|---|---|---|
1000 | 1 | 0.004 | 0.002 | 0.001 |
10000 | 1 | 0.038 | 0.017 | 0.009 |
100000 | 1 | 0.730 | 0.511 | 0.407 |
1000000 | 1 | 1.209 | 1.444 | 1.693 |
5000000 | 1 | 1.314 | 1.556 | 1.654 |
规模/线程数 | 1 | 2 | 4 | 8 |
---|---|---|---|---|
10000 | 0.000087 | 0.004757 | 0.025594 | 0.040260 |
100000 | 0.000416 | 0.015015 | 0.036435 | 0.054088 |
1000000 | 0.003892 | 0.029813 | 0.045457 | 0.060422 |
10000000 | 0.047871 | 0.037937 | 0.055264 | 0.070782 |
100000000 | 0.410810 | 0.330348 | 0.282296 | 0.307018 |
1000000000 | 8.801296 | 5.527966 | 3.751501 | 2.940126 |
规模/线程数 | 1 | 2 | 4 | 8 |
---|---|---|---|---|
10000 | 1 | 0.018 | 0.003 | 0.002 |
100000 | 1 | 0.028 | 0.011 | 0.008 |
1000000 | 1 | 0.131 | 0.086 | 0.064 |
10000000 | 1 | 1.262 | 0.866 | 0.676 |
100000000 | 1 | 1.244 | 1.455 | 1.338 |
1000000000 | 1 | 1.592 | 2.346 | 2.994 |
分析与总结
当数据比较小时,进程的创建和同步等因多进程而导致的开销是加速比小于1的主要原因。随着数据的增大,计算的开销越来越大,这种额外开销占比越来越小,多线程并行计算的优点逐渐体现出来,因此加速比也随之增加并且超过1。
当数据较大时,随着线程数的增加,加速比虽然也在增加,但是增加速率很小,部分原因是多线程导致的额外开销随着线程数增加而增加,更重要的原因在于当线程数超过CPU核数时(本实验为双核)CPU占有率会达到极限,很难再有提升。
利用 MPI 求素数个数相关推荐
- 利用函数求两个数的最大值
利用函数求两个数的最大值 <!DOCTYPE html> <html lang="en"><head><meta charset=&quo ...
- python3,利用函数求两个数的和与差。
基础内容: 相信很多刚接触 python 的同学都有遇到过这种题.以下是 在 python 中的利用函数求两个数的和与差. class Calculate: def --init--(self,num ...
- c语言,求素数个数,关于求素数个数的话题
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #include int *prime, *v; int q = 1, p = 1; int pi(int n, in ...
- 求质数个数(求素数个数
以洛谷p3912为例 题目描述 求 1,2,⋯,N 中素数的个数. 输入格式 一行一个整数 N. 输出格式 一行一个整数,表示素数的个数. 示例: 输入: 10 输出: 4 解释: 小于 10 的质数 ...
- 求素数个数【C语言】
素数 素数也叫质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数. 暴力算法 思路:通过把每一个数从2开始进行求余,能整除的就不是素数,否则就是素数 #include <std ...
- 7-2 求素数个数 (30分)
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> ...
- C语言 利用函数计算素数个数并求和
素数就是只能被1和自身整除的正整数,例如,1不是素数,2是素数.输入两个正整数m和n(1<=m,n<=500),统计并输出m到n之间的素数的个数以及这些素数. 要求定义并调用函数prime ...
- 利用函数求三个数的最大值
我率先抄书 #include<stdio.h> int main() {int max(int x, int y);//声明函数maxint a, b, c, d;scanf(" ...
- 求三个数的最小公倍数的解法之美
从键盘上输入三个数,求其最小公倍数. 分析:最小公倍数是指能整除这三个数的公倍数中的最小者,可以利用循环穷举的方法,看是否能整除这三个数.若能整除这三个数,则输出其中的最小的数即为最小公倍数. 第一种 ...
最新文章
- 认识人和鱼的AI,能识别美人鱼吗?阿里CVPR论文试用因果推理方法解答
- python教程:关于 [lambda x: x*i for i in range(4)] 理解
- 全栈工程师之路(二)—— JavaScript(网页前端脚本语言)
- irobot擦地机器人故障_irobot擦地机器人有必要入手吗?
- Flink countWindow窗口
- unity android 符号表,记录腾讯bugly关于符号表的配置
- http --- 缓存
- NET主流ORM框架分析
- linux输出文件没有找到,Linux环境下标准输入、输出、错误信息详解
- CentOS 7下基于bitnami的Redmine结合Subversion的设置
- Opencv创建纯色图
- 微信html5活动页面制作,完整的微信H5活动页面设计规范
- java在退出前释放资源_【java】手动释放资源问题
- C语言爱心代码大全集—会Ctrl+C就可以表白了
- 旋转曲面的面积——微元法【】
- maxent阈值使用
- P-touch Editor 批量打印标签
- Windows一键删除指定文件或文件夹
- 删除链接文件 linux,rm 删除链接文件的问题
- seo有什么特点优点,分享seo优化的7个好处
热门文章
- 数据分析学习笔记 —编译性语言和解释性语言区别
- 人生苦短快用python_人生苦短,快用 Python
- angular js 使用pdf.js_胶水(框架) Stencil.js
- java五层架构_Web五层架构
- ios pan手势滑动消失动画_iOS仿抖音—评论视图滑动消失
- 汉子拼音不认识缤纷_儿童学拼音app哪个最好
- pytorch学习笔记(三十一):门控循环单元(GRU)
- java 统计字符串中每个字符出现的次数(数组或HashMap实现)
- ChEMBL数据库的官方python工具包
- [转]远远走来一个绿茶婊