题目

结合高性能并行计算领域算例,使用MPI + OpenMP并行化编写代码,并撰写报告,测试并行效率。

方法

  1. 定义快速排序quickSort函数,定义排序总数NUM;
  2. 生成大小为size * calculateSize的二维逆序数组,其中使用MPI_Comm_size获取size,size * calculateSize = NUM;
  3. MPI_Comm_rank获取进程ID,通过通信函数MPI_Scatter将每个子矩阵发送到每个子进程,然后每个子进程通过quickSort函数进行快速排序,使用OpenMP的sections集合函数进行线程划分;
  4. 将每个子进程通过通信函数MPI_Gather收回到0号进程中,再对收回了所有数的0号进程中的数组进行最后一次排序,即size路归并排序,就能得到排完序的数组;
  5. 利用MPI_Wtime()函数进行计时。

代码

#include "mpi.h"
#include "omp.h"
#include <iostream>
#define NUM 12800
using namespace std;void swap(int &a, int &b)  //交换函数
{int temp;temp = a;a = b;b = temp;
}void printArray(int *array, int len)  //输出数组
{for (int i = 0; i < len; i++)cout << array[i] << " ";cout << endl;
}void quickSort(int *array, int l, int r)  //快速排序
{int i, m;if (l >= r) return;m = l;for (i = l + 1; i <= r; i++)if (array[i] < array[l])swap(array[++m], array[i]);swap(array[l], array[m]);#pragma omp parallel sections  //sections使用2个线程即两个并行块{#pragma omp sectionquickSort(array, l, m - 1);#pragma omp sectionquickSort(array, m + 1, r);};
}int main(int argc, char *argv[])
{double time;  //时间标记time = MPI_Wtime();  //返回调用处理器上经过的挂钟时间MPI_Init(&argc, &argv);  //MPI初始化int size;  //通信域comm中所包含的进程数MPI_Comm_size(MPI_COMM_WORLD, &size); //返回指定通信器中MPI进程的总数int calculateSize = (int)(NUM / size);  //每个进程分配的计算个数int processId;  //进程在comm中的标识号idMPI_Comm_rank(MPI_COMM_WORLD, &processId);  //获取MPI进程编号int arr[size][calculateSize];  //初始数组int arrMerge[size][calculateSize];  //合并数组int arrEach[calculateSize];  //size分之一个初始数组的数int figure = size * calculateSize;  //用于给数组赋值int arrFinal[size * calculateSize];  //排完序的完整数组for (int i = 0; i < size; i++)  //生成数组{for (int j = 0; j < calculateSize; j++) {arr[i][j] = figure--;}}//并行排序,将数组平均分成size块后分给每个子进程排序MPI_Scatter(arr, calculateSize, MPI_INT, arrEach, calculateSize, MPI_INT, 0, MPI_COMM_WORLD);    //每个进程里的排序quickSort(arrEach, 0, calculateSize - 1);//将子进程排完序的数组合并成一个MPI_Gather(arrEach, calculateSize, MPI_INT, arrMerge, calculateSize, MPI_INT, 0, MPI_COMM_WORLD);cout << "The current array of " << processId << ":" << endl;  //输出当前进程排序结果printArray(arrEach, calculateSize);//数组用于记录存放选择次数int numTimes[size] = {0};//用于存放合并数组时最大的四个数的数组int arrNumMax[size];for (int i = calculateSize * size - 1; i >= 0; i--)  //按升序顺序合并为一个数组{for (int j = 0; j < size; j++)  //找出szie个数组里面分别最大的数{if (numTimes[j] >= calculateSize)arrNumMax[j] = 0;elsearrNumMax[j] = arrMerge[j][calculateSize - numTimes[j] - 1];}int maxNum = arrNumMax[0];  //找出size个数里面最大的数即size路归并for (int k = 1; k < size; k++){if (arrNumMax[k] > maxNum)maxNum = arrNumMax[k];}for (int n = 0; n < size; n++)  //标记数最大的数组{if (maxNum == arrNumMax[n]){numTimes[n] = numTimes[n] + 1;break;}}arrFinal[i] = maxNum;  //存入数组}if (!processId)  {time = MPI_Wtime() - time;  //结束计时cout << "The final array :" << endl;  //输出数组printArray(arrFinal, size * calculateSize);cout << "NUM = "<< NUM << "\t" << "size = " << size << "\t" << "time = " << time * 1000 << " ms" << endl;}MPI_Finalize();  //终止MPIreturn 0;
}

结果分析

1、简单输出测试:共100个数据进行排序,使用10个进程,其中线程数export OMP_NUM_THREADS=2。

$ mpicc -o quicksort -fopenmp quicksort.cpp -lstdc++
$ time mpirun -np 10 ./quicksort
The current array of 2:
71 72 73 74 75 76 77 78 79 80
The current array of 5:
41 42 43 44 45 46 47 48 49 50
The current array of 6:
31 32 33 34 35 36 37 38 39 40
The current array of 7:
21 22 23 24 25 26 27 28 29 30
The current array of 9:
1 2 3 4 5 6 7 8 9 10
The current array of 1:
81 82 83 84 85 86 87 88 89 90
The current array of 4:
51 52 53 54 55 56 57 58 59 60
The current array of 0:
91 92 93 94 95 96 97 98 99 100
The final array :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Parallel running time = 54.8629 ms
The current array of 3:
61 62 63 64 65 66 67 68 69 70
The current array of 8:
11 12 13 14 15 16 17 18 19 20

结果分析:程序会根据输入进程数自动平均分配排序任务,因此采用二维数组方便进行数据的分布与收集,初始数组为逆序,每个进程排序完毕后进行归并收集,最后变为升序数组。

2、效率测试:在排序总数NUM=10000时,测试不同进程数对时间的影响。


结果分析:在本实验中,线程数设置为2;由于通信函数MPI_Scatter限制,故进程数选择需要能被10000整除。通过实验数据可得,当排序数目为10000时,进程数5的时间最快,也具有不错的效率;随着进程数不断增加,如50时,每个进程需要排序2000个数据,使得通信花费大于排序花费,因此时间反弹。

总结

在大规模节点间的并行时,由于节点间通讯的量是成平方项增长的,所以带宽很快就会显得不够。所以用MPI+OpenMP混合编写并行部分,即每个MPI进程执行多个OpenMP线程。OpenMP部分由于不需要进程间通信,直接通过内存共享方式交换信息,所以可以显著减少程序所需通讯的信息。

MPI + OpenMP实现快速排序相关推荐

  1. 【MPI OpenMP】并行蒙特卡洛方法求圆周率(C语言)

    本文记录了使用MPI与OpenMP两种并行计算方法实现蒙特卡洛计算圆周率,题目是专业实验课上老师给的,主要分享一下自己的做法,希望大家不吝赐教(使用的语言是C语言). 蒙特卡洛方法求圆周率 蒙特卡洛方 ...

  2. 利用 MPI 求素数个数

    实验题目 实验题目 利用 MPI,OpenMP 编写简单的程序,测试并行计算系统性能 实验内容 两道题,每道题需要使用 MPI 和 OpenMP 分别实现: 求素数个数 实验描述: 给定正整数 n,编 ...

  3. 使用VS2019+Intel OneAPI (ifort)+Intel MPI编译和运行MPI程序与Coarray程序

    使用VS2019+Intel OneAPI (ifort)+Intel MPI编译和运行MPI程序与Coarray程序 一.安装环境 安装vs2019 安装Intel OneAPI Base Tool ...

  4. Ubuntu下安装配置TAU分析mpich和openmp程序性能

    目录 1. 安装MPICH 2. 安装JAVA环境 3. 下载TAU(及PDT) 4. 提取并配置安装 4.1 使用图形化界面安装 4.2 使用终端直接配置 5. 配置Vs Code或直接使用终端编译 ...

  5. 大数据学习(07)--MapReduce

    文章目录 目录 1.MapReduce介绍 1.1 什么是分布式并行编程? 1.2 MapReduce模型介绍 1.3 map和reduce函数 2.MapReduce体系架构 3.MapReduce ...

  6. 生物效应大数据评估聚类算法的并行优化

    生物效应大数据评估聚类算法的并行优化 彭绍亮1,2,杨顺云2,孙哲1,程敏霞1,崔英博2,王晓伟2,李非3,伯晓晨3,廖湘科2 1. 湖南大学信息科学与工程学院&国家超级计算长沙中心,湖南 长 ...

  7. C++ SuperLU 混合编程

    1. 软件版本信息 Windows 10 Visual Studio 2015 Professional SuperLU Package 2.  软件下载链接 SuperLU Introduction ...

  8. Haskell大世界+思考

    文章目录 基石般灵活表现自由的抽象范式 编程语言是什么? 推荐论文 大佬建议 Meta Haskell 实现 类型系统 语言抽象/模式 问题解决方案 Haskell在工业界有哪些实际的应用? 关于fp ...

  9. 高性能计算机系统硬件结构图,硬件资源

    "天河"超级计算机首次提出 CPU+GPU 的异构融合并行计算体系结构,提出CPU 和 GPU 相结合的高性能计算与效率优化的理论和途径,探索面向科学工程计算的新型加速技术与方法, ...

  10. 图灵奖得主Jack Dongarra:高性能计算与AI大融合,如何颠覆科学计算

    导读:浩瀚的宇宙中两个星云不断彼此接近.融合.再爆炸,这样奇幻的天文景观正是采用高性能计算(HPC)进行建模仿真生成的. 在过去的三十年间,高性能计算(HPC)取得了突飞猛进的进展,在科学计算等领域发 ...

最新文章

  1. 爬虫之xpath语法-常用节点选择语法
  2. 由laravel 5.5无法获取url中的参数引发的apache的.htaccess文件问题
  3. 第六十节,文本元素标签
  4. oracle 10g gateway 安装操作,Oracle 10g RAC启动节点报错 Default gateway is not defined
  5. 【渝粤题库】陕西师范大学202081 管理学 作业 (专升本、高起本、高起专)
  6. ucache灾备云报价_UCACHE灾备云功能
  7. 弹出层中都可以用的复制功能
  8. php接收base64图片并保存
  9. PAT 乙级 1043. 输出PATest(20) Java版
  10. C语言之父:我创造了C语言,但这些书帮我表达了出来
  11. 期货反跟单软件介绍与反跟单交易中的骗局
  12. Tcplistener服务端与tcpclient客户端使用
  13. 苦橙花---不喧哗,自有声
  14. C51_将按键次数写入AT24C02,再读出送LCD显示
  15. (c++)编写函数fac(n),用递归法求出n的阶乘.在程序中使用此函数,将输入的整数n的阶乘求出并输出到控制台.
  16. 连上WiFi就能打电话?“手机营业厅”中的神奇功能火了
  17. 云服务器Linux 安装SVN
  18. 2023最近很火的抖音解封技术教程分析+价值1000+
  19. SpringBoot 接口数据加解密实战
  20. 安装 libtorrent遇到问题

热门文章

  1. python 处理 图像和视频
  2. linux系统编译时make出错,centos 编译安装cmake和常见过程错误解决办法(linux系统均适用,以爬坑。。)...
  3. web前端学习的职业发展方向
  4. Spring Cloud负载均衡,报错:No instances available for localhost
  5. 关于iconfont字体图标在IE上无法显示的问题
  6. LeetCode(查找元素的第一个和最后一个位置)
  7. 机器翻译模型简介(一)
  8. 如何面试大厂web前端?(沟通软技能总结)
  9. 电商购物评论的情感分析
  10. 怎样才能成为挑战年薪30W的运维工程师?