9.高性能计算 期末复习
文章目录
- 1.提纲
- 2.第二章 并行硬件&程序设计
- 2.1 SIMD&MIMD
- 2.2 可扩展性
- 2.7 串行程序并行化(poster四步:划分、通信、聚合、分配)
- 3.mpi
- 2.1 点对点
- gemm
- 2.2集合通信
- gemm
- send/recv实现reduce
- send/recv 实现ring AllReduce
- 2.3 加速比
- 2.4 奇偶冒泡排序
- 4. pthread
- 4.1 gemm
- 4.2 临界区
- 1.忙等待
- 2.互斥量
- 3.信号量
- 4. 生产消费者模型
- 方程的根
- reader-writer
- 5.缓存一致性
- 6.伪共享
- 4.3 求pi: critical_sections problem
- 5.openmp
- 5.1 parallel
- 5.2 奇偶冒泡排序
- 5.3 数据依赖
- 6.GPU
1.提纲
实验
MPI:send,rcv,点对点实现集合通信(伪代码)
pthread:gemm,求方程的根(生产消费),缓存一致性,临界区的限制
openmp:
gemm:MPI实现,pthread实现
第二章:并行硬件&程序设计
2.3 SIMD,MIMD,缓存一致性
2.4 分布式内存与共享式内存(MPI和pthread)
2.5 加速比、阿姆达尔定律、强弱可扩展性
2.7 串行程序并行化(poster四步:划分、通信、聚合)
第三章:MPI
点对点:send,rcv
通信集:MPI_Reduce/MPI_AllReduce(用send和recv实现),scatter,gather
3.6 MPI_time:系统时间,算加速比(pthread要用系统时间)
奇偶排序冒泡排序
第四章:Pthread
4.2 线程创建与销毁:thread_create, thread_join
4.3 临界区:解决方案与效率
忙等待:实现
互斥量:
信号量:
4.7 生产消费者模型
读写锁: https://cloud.tencent.com/developer/article/1021461
读多写少
4.10 缓存一致性 https://www.cnblogs.com/xiaolincoding/p/13886559.html
第五章: openmp
parallel for等语法: https://learn.microsoft.com/zh-cn/cpp/parallel/openmp/reference/openmp-directives?source=recommendations&view=msvc-170
数据依赖
奇偶冒泡排序
子句:Reduction, 锁 https://blog.csdn.net/qq_43219379/article/details/123911644
六、GPU: 概念解释
物理组织:GPC,TPC,SM,wrap,SP
逻辑结构:grid,block,thread
2.第二章 并行硬件&程序设计
2.1 SIMD&MIMD
SIMD
MIMD
2.2 可扩展性
效率与可扩展:
强弱可扩展性:
2.7 串行程序并行化(poster四步:划分、通信、聚合、分配)
3.mpi
2.1 点对点
send,rcv
gemm
#include<stdio.h>
#include<stdlib.h>
#include<mpi.h>
#include<iostream>int main(int argc, char * argv[] ){double startTime, stopTime;double *a, *b, *c;int m,n,k;m=atoi(argv[1]);n=atoi(argv[2]);k=atoi(argv[3]);int rank, numprocs, lines;MPI_Init(NULL,NULL);MPI_Comm_rank(MPI_COMM_WORLD, &rank);MPI_Comm_size(MPI_COMM_WORLD, &numprocs);lines = m/numprocs;//lines that each thread processa = new double[m * n];b = new double[n * k];c = new double[m * k];if( rank ==0 ){double *c_buffer = new double[lines * k];srand((unsigned)time(0));gen_matrix(a,m,n);gen_matrix(b,n,k);startTime = MPI_Wtime();//send datafor(int i=1;i<numprocs;i++){//send whole BMPI_Send( b, n*k, MPI_DOUBLE, i, 0, MPI_COMM_WORLD );}for(int i=1;i<numprocs;i++){//send part AMPI_Send( a + (i-1)*lines*n, n*lines, MPI_DOUBLE, i, 1, MPI_COMM_WORLD);}//thread 0 compute the last part Afor (int i = (numprocs - 1) * lines; i < m; i++){for(int j=0;j<k;j++){double temp = 0;for(int t=0;t<n;t++)temp += a[i*n+t]*b[t*k+j];c[i*k+j] = temp;}}//recv resultfor (int t = 1; t < numprocs; t++){MPI_Recv(c_buffer, lines * k, MPI_DOUBLE, t, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE);//copy ans to cfor(int i=0;i<lines;i++){for(int j=0;j<k;j++){c[((t - 1) * lines + i) * k + j] = c_buffer[i * k + j];}}}stopTime = MPI_Wtime();printf("计算所用时间:%lfs\n",stopTime-startTime);delete[] c_buffer;}else{double *a_buffer = new double[n * lines];double *b_buffer = new double[n * k];double *local_ans=new double[lines*k];MPI_Recv(b_buffer, n * k, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);MPI_Recv(a_buffer, n * lines, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);for(int i=0;i<lines;i++){for(int j=0;j<k;j++){double temp=0;for(int t=0;t<n;t++)temp += a_buffer[i * n + t] * b_buffer[t * k + j];local_ans[i * k + j] = temp;}}MPI_Send(local_ans, lines * k, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD);delete[] a_buffer;delete[] b_buffer;delete[] local_ans;}delete[] a;delete[] c;delete[] b;MPI_Finalize();return 0;
}
2.2集合通信
MPI_Reduce/MPI_AllReduce(用send和recv实现),scatter,gather
MPI API 参考: https://zhuanlan.zhihu.com/p/70703729
MPI API 参考: https://mpitutorial.com/tutorials/
广播:
int MPI_Bcast(void* buffer,int count,MPI_Datatype datatype,int root, MPI_Comm comm)
buffer 消息缓冲的起始地址
count 数据的数量
datatype 广播的数据类型
root 广播进程
comm 通信组
Scatter:
int MPI_Scatter(void* sendbuf, int sendcount, MPI_Datatype sendtype,void* recvbuf, int recvcount, MPI_Datatype recvtype,int root, MPI_Comm comm)
sendbuf 发送消息缓冲区的起始地址
sendcount 发送到各个进程的数据个数
sendtype 发送消息缓冲区中的数据类型
recvbuf 接收消息缓冲区的起始地址
recvcount 待接收的元素个数
recvtype 接收元素的数据类型
root 发送进程的序列号
comm 通信域
Gather:
int MPI_Gather(void* sendbuf, int sendcount, MPI_Datatype sendtype,void* recvbuf, int recvcount, MPI_Datatype recvtype,int root, MPI_Comm comm)
sendbuf 发送消息缓冲区的起始地址
sendcount 发送消息缓冲区中的数据个数
sendtype 发送消息缓冲区中的数据类型
recvbuf 接收消息缓冲区的起始地址(各个进程传回root的数据会自动按进程编号排列放到内存中)
recvcount 待接收的元素个数(每个进程的元素个数,而非所有线程总的元素个数)
recvtype 接收元素的数据类型
root 接收进程的序列号
comm 通信域
MPI_Reduce
MPI_Reduce(void* send_data,void* recv_data,int count,MPI_Datatype datatype,MPI_Op op,//MPI_MAX, MPI_SUM...int root,//the rank of root threadMPI_Comm communicator)
例子:求和,然后计算平均值
float *rand_nums = NULL;
rand_nums = create_rand_nums(num_elements_per_proc);// Sum the numbers locally
float local_sum = 0;
int i;
for (i = 0; i < num_elements_per_proc; i++) {local_sum += rand_nums[i];
}// Print the random numbers on each process
printf("Local sum for process %d - %f, avg = %f\n",world_rank, local_sum, local_sum / num_elements_per_proc);// Reduce all of the local sums into the global sum
float global_sum;
MPI_Reduce(&local_sum, &global_sum, 1, MPI_FLOAT, MPI_SUM, 0,MPI_COMM_WORLD);// Print the result
if (world_rank == 0) {printf("Total sum = %f, avg = %f\n", global_sum,global_sum / (world_size * num_elements_per_proc));
}
MPI_AllReduce: Combines values from all processes and distributes the result back to all processes.
//不需要根进程 ID(因为结果分配给所有进程)
MPI_Allreduce(void* send_data,void* recv_data,int count,MPI_Datatype datatype,MPI_Op op,MPI_Comm communicator)
MPI_Allreduce
等效于先执行 MPI_Reduce
,然后执行 MPI_Bcast
gemm
A用scatter给每个进程分发一部分,B用broadcast完整地广播到所有进程,计算完毕后,用gather收集C。
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <iostream>int main(int argc, char *argv[])
{double startTime, stopTime;int m, n, k;m = atoi(argv[1]);n = atoi(argv[2]);k = atoi(argv[3]);int my_rank, numprocs, lines;MPI_Init(NULL, NULL);MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);MPI_Comm_size(MPI_COMM_WORLD, &numprocs);lines = m / numprocs;double *a = new double[m * n];double *b = new double[n * k];double *c = new double[m * k];double *local_a = new double[lines * n];double *local_c = new double[m * k];if (my_rank == 0){//prepare datasrand((unsigned)time(0));gen_matrix(a, m, n);gen_matrix(b, n, k);startTime = MPI_Wtime();}// Send: Scatter A, Bcast whole BMPI_Scatter(a, lines * n, MPI_DOUBLE, local_a, lines * n, MPI_DOUBLE, 0, MPI_COMM_WORLD);MPI_Bcast(b, n * k, MPI_DOUBLE, 0, MPI_COMM_WORLD);// All processes involve calculationfor (int i = 0; i < lines; i++){for (int j = 0; j < k; j++){double temp = 0;for (int t = 0; t < n; t++)temp += local_a[i * n + t] * b[t * k + j];local_c[i * k + j] = temp;}}// Recv: Gather CMPI_Gather(local_c, lines * k, MPI_DOUBLE, c, lines * k, MPI_DOUBLE, 0, MPI_COMM_WORLD);if (my_rank == 0){stopTime = MPI_Wtime();printf("计算所用时间:%lfs\n", stopTime - startTime);}delete[] a;delete[] b;delete[] c;delete[] local_a;delete[] local_c;MPI_Finalize();return 0;
}
send/recv实现reduce
send/recv 实现ring AllReduce
课堂测试题: 设10个进程,每个进程有长度10000的数组,给出基于MPI Send和 Recv函数实现Ring Allreduce函数的伪代码。
Ring allreduce是一种最优通信算法。环中的计算节点都被安排在一个逻辑环中。每个计算节点应该有一个左邻和一个右邻,它只会向它的右邻居发送数据,并从它的左邻居接收数据。
该算法分两个步骤进行:首先是scatter-reduce,然后是allgather。在scatter-reduce步骤中,GPU将交换数据,使每个GPU可得到最终结果的一个块。在allgather步骤中,gpu将交换这些块,以便所有gpu得到完整的最终结果。
第一阶段通过(N-1)步,让每个节点都得到1/N的完整数据块。每一步的通信耗时是α+S/(NB),计算耗时是(S/N)* C。 这一阶段也可视为scatter-reduce。
第二阶段通过(N-1)步,让所有节点的每个1/N数据块都变得完整。每一步的通信耗时也是α+S/(NB),没有计算。这一阶段也可视为allgather。
伪代码:
myrank
//scatter-reduce
For i =1->N-1send(blok myrank, (myrank+1)%N)//向下一个节点发送数据块recv(rc_buffer, (myrank-1)%N)//从前一个节点接收数据块add(rc_buffer,block N-myrank)//求和//allgather
For i =1->N-1send(blok N-myrank, (myrank+1)%N)//向下一个节点发送数据块recv(rc_buffer, (myrank-1)%N)//从前一个节点接收数据块store(rc_buffer,block myrank)//用"全局和"覆盖本地数据块
2.3 加速比
MPI_ Wtime返回墙上时钟时间。回想-一下,C语言中的c1ock函数返回的是CPU时间(包括用户代码、库函数以及系统调用函数所消耗的时间),但它不包括空闲时间,而在并行程序中,很多情况下都是空闲等待状态。例如,调用MPI_ Recv会消耗很多时间来等待消息的到达。而墙上时钟时间给出了所经历的全部时间,包括空闲等待时间。
加速比:最理想是p
并行的效率:每个进程的加速比
例子:理论作业1 2.16
假定一个串行程序的运行时间为
9.高性能计算 期末复习相关推荐
- 《数据仓库与数据挖掘》期末复习总结
<数据仓库与数据挖掘>期末复习总结 适用教材:<数据挖掘概念与技术(第3版)>,Jiawei Han,Mieheline Kamber,Jian Pei著,机械工业出版社 提示 ...
- 广东电大计算机绘图试题,电大计算机绘图期末复习试题及答案参考小抄.doc
电大计算机绘图期末复习试题及答案参考小抄 一.填空题(每小题1.5分,共30分) 1.CAD的常用图形输入设备有???鼠标??.数字化仪.图形输入板.光笔.??键盘 等.2.CAD的软件可分为系统软件 ...
- 太牛了 Python期末复习总结,提高成绩必备回家过个开心年
Python期末复习之语法 将用一张思维导图的形式来展示python的基础语法. Python期末复习之运算符 Python语言支持以下类型的运算符: 算术运算符 比较(关系)运算符 赋值运算符 逻辑 ...
- java语言程序设计期末复习综合练习题_Java语言程序设计期末复习综合练习题答案...
Java语言程序设计期末复习综合练习题 一.选择题. 2. main方法是Java Application程序执行的入口点,关于main方法的方法头以下哪项是合法的( )? A.public stat ...
- (52 90) 简答 什么叫计算机网络,计算机网络期末复习试卷.doc
计算机网络期末复习试卷 计算机网络模拟试题及参考答案 一.填空题 1.数据链路层的主要任务是在相邻结点间的线路上无差错地传送以帧为单位的数据,网络层的主要任务是选择合适的路由,应用层的主要任务就是将各 ...
- 计算机组成原理考试知识点总结,最新2018计算机组成原理期末复习考试知识点复习考点归纳总结总结...
电大计算机组成原理期末复习考试考点 归纳总结 科学研究和工程技术计算是计算机最早的领域. 信息处理是计算机应用的最广泛的领域. 计算机系统分为硬件和软件两大部分.硬件是实体部件,是看得见摸得着的.软件 ...
- 微型计算机滑动平均值滤波器方程,微型计算机控制技术期末复习2011.ppt
期末复习提纲,考试范围,第二章模拟量输入输出通道接口技术第三章人机交互接口技术第四章常用控制程序设计第六章总线接口技术第七章过程控制数据处理方法第八章PID算法第十一章微机控制系统抗干扰设计,试题题型 ...
- 2020年通信网络基础期末复习
文章目录 期末考试(已删除!) 平时作业题汇总 写在最后 写在前面: 第一,现在是2021年6月28日19点46分,之前的文章需要填坑!男人嘛,言而有信. 第二,写这篇文章之日,距离考试接近一载光阴, ...
- 通信网络基础期末复习与汇总
计算机网络课程 期末复习汇总,方便自己复习总结. [1]通信网络基础期末复习-第一章和第二章-概论和端到端的传输协议 [2]通信网络基础期末复习-第三章-网络的时延分析 [3]通信网络基础期末复习-第 ...
最新文章
- SpringBoot使用教程【1】Restful API设计 返回json,xml格式...
- Tools.Png.Compression
- 小F的2013应届校招历程小结
- Python绘图之matplotlib基础教程:matplotlib库图表绘制中常规设置大全(交互模式、清除原有图像、设置横坐标显示文字/旋转角度、添加图例、绘图布局自动调整、图像显示、图像暂停)
- 垂直居中重要方法理解---重点是方法三
- 直方图均衡 视觉显著_视觉图像:对比度受限直方图均衡化CLAHE
- 面试题:MySQL的innodb和myisam
- Java高级语法笔记-内部类
- python中print不显示结果_Python中的print()函数
- SQL Server Reporting Services最佳做法
- Python实现计算图像RGB均值
- 计算机科学导论的试题,《计算机科学导论》期末考试试题
- 新浪云 node.js项目的部署
- Django中related_name作用
- react-use react hook 库
- 完美解决Pycharm报错[WinError 193] %1 不是有效的 Win32 应用程序
- Uni-app 小程序使用腾讯云IM实时通讯
- 关于DSSD算法相关解析
- 工具学习——有哪些好用的学术翻译工具
- 深入剖析基于并发AQS的(独占锁)重入锁(ReetrantLock)及其Condition实现原理
热门文章
- 服装办理erp体系的优点与选择
- 【自存代码】划分数据集为训练集和测试集
- Google Chorme
- 巨多的笑话,让心情放飞一下吧..
- android 人工智能测试,人工智能(AI)测试方法
- 惠普HP Deskjet Ink Advantage 3540 打印机驱动
- 高端运动耳机哪个品牌最好、最好的运动耳机品牌排行
- 三角形面积的勾股定理
- axure树形表格_表格 树形菜单/excel 如何实现分级显示,也就是树形的菜单
- docekr unable to delete d38d835588d5 (must be forced) - image is referenced in multiple repositories