实验题目

  1. 实验题目
    利用 MPI,OpenMP 编写简单的程序,测试并行计算系统性能
  2. 实验内容
    两道题,每道题需要使用 MPI 和 OpenMP 分别实现:

    1. 求素数个数

      1. 实验描述:
        给定正整数 n,编写程序计算出所有小于等于 n 的素数的个数
      2. 实验要求:
        需要测定 n=1,000;10,000;100,000;500,000(逗号仅为清晰考虑)时程序运行的时间
    2. 求 Pi 值
      1. 实验描述:
        给定迭代次数 n,编写程序计算 Pi 的值
      2. 实验要求:
        算法必须使用近似公式求解。需要测定 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);
}

实验结果

求素数个数 MPI 运行时间(s)
规模/线程数 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
求素数个数 MPI 加速比
规模/线程数 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
求PI MPI 运行时间(s)
规模/线程数 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
求PI MPI 加速比
规模/线程数 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的主要原因。随着数据的增大,计算的开销越来越大,这种额外开销占比越来越小,多线程并行计算的优点逐渐体现出来,因此加速比也随之增加并且超过1。

  2. 当数据较大时,随着线程数的增加,加速比虽然也在增加,但是增加速率很小,部分原因是多线程导致的额外开销随着线程数增加而增加,更重要的原因在于当线程数超过CPU核数时(本实验为双核)CPU占有率会达到极限,很难再有提升。

利用 MPI 求素数个数相关推荐

  1. 利用函数求两个数的最大值

    利用函数求两个数的最大值 <!DOCTYPE html> <html lang="en"><head><meta charset=&quo ...

  2. python3,利用函数求两个数的和与差。

    基础内容: 相信很多刚接触 python 的同学都有遇到过这种题.以下是 在 python 中的利用函数求两个数的和与差. class Calculate: def --init--(self,num ...

  3. c语言,求素数个数,关于求素数个数的话题

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #include int *prime, *v; int q = 1, p = 1; int pi(int n, in ...

  4. 求质数个数(求素数个数

    以洛谷p3912为例 题目描述 求 1,2,⋯,N 中素数的个数. 输入格式 一行一个整数 N. 输出格式 一行一个整数,表示素数的个数. 示例: 输入: 10 输出: 4 解释: 小于 10 的质数 ...

  5. 求素数个数【C语言】

    素数 素数也叫质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数. 暴力算法 思路:通过把每一个数从2开始进行求余,能整除的就不是素数,否则就是素数 #include <std ...

  6. 7-2 求素数个数 (30分)

    #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> ...

  7. C语言 利用函数计算素数个数并求和

    素数就是只能被1和自身整除的正整数,例如,1不是素数,2是素数.输入两个正整数m和n(1<=m,n<=500),统计并输出m到n之间的素数的个数以及这些素数. 要求定义并调用函数prime ...

  8. 利用函数求三个数的最大值

    我率先抄书 #include<stdio.h> int main() {int max(int x, int y);//声明函数maxint a, b, c, d;scanf(" ...

  9. 求三个数的最小公倍数的解法之美

    从键盘上输入三个数,求其最小公倍数. 分析:最小公倍数是指能整除这三个数的公倍数中的最小者,可以利用循环穷举的方法,看是否能整除这三个数.若能整除这三个数,则输出其中的最小的数即为最小公倍数. 第一种 ...

最新文章

  1. 认识人和鱼的AI,能识别美人鱼吗?阿里CVPR论文试用因果推理方法解答
  2. python教程:关于 [lambda x: x*i for i in range(4)] 理解
  3. 全栈工程师之路(二)—— JavaScript(网页前端脚本语言)
  4. irobot擦地机器人故障_irobot擦地机器人有必要入手吗?
  5. Flink countWindow窗口
  6. unity android 符号表,记录腾讯bugly关于符号表的配置
  7. http --- 缓存
  8. NET主流ORM框架分析
  9. linux输出文件没有找到,Linux环境下标准输入、输出、错误信息详解
  10. CentOS 7下基于bitnami的Redmine结合Subversion的设置
  11. Opencv创建纯色图
  12. 微信html5活动页面制作,完整的微信H5活动页面设计规范
  13. java在退出前释放资源_【java】手动释放资源问题
  14. C语言爱心代码大全集—会Ctrl+C就可以表白了
  15. 旋转曲面的面积——微元法【】
  16. maxent阈值使用
  17. P-touch Editor 批量打印标签
  18. Windows一键删除指定文件或文件夹
  19. 删除链接文件 linux,rm 删除链接文件的问题
  20. seo有什么特点优点,分享seo优化的7个好处

热门文章

  1. 数据分析学习笔记 —编译性语言和解释性语言区别
  2. 人生苦短快用python_人生苦短,快用 Python
  3. angular js 使用pdf.js_胶水(框架) Stencil.js
  4. java五层架构_Web五层架构
  5. ios pan手势滑动消失动画_iOS仿抖音—评论视图滑动消失
  6. 汉子拼音不认识缤纷_儿童学拼音app哪个最好
  7. pytorch学习笔记(三十一):门控循环单元(GRU)
  8. java 统计字符串中每个字符出现的次数(数组或HashMap实现)
  9. ChEMBL数据库的官方python工具包
  10. [转]远远走来一个绿茶婊