高性能计算实验——矩阵乘法基于MPI的并行实现及优化

2023-11-10

1.实验目的

1.1.通过MPI实现通用矩阵乘法

熟练掌握MPI编程方法,并将通用矩阵乘法转为MPI并行实现,进一步加深MPI的使用与理解。

1.2.基于MPI的通用矩阵乘法优化

进一步熟悉MPI矩阵乘法的实现,学习MPI点对点通信与集合通信的异同点和各自的优缺点,学会比较二者的性能以及各自使用的情形。

1.3.改造实验1成矩阵乘法库函数

学习如何将自己编写的代码改造为标准库函数,供其他程序调用。
理解动态链接的过程。

2.实验过程和核心代码

2.1.通过MPI实现通用矩阵乘法

2.1.1.问题描述
通过 MPI 实现通用矩阵乘法(实验1)的并行版本,MPI并行进程(rank size)从 1 增加至 8,矩阵规模从 512 增加至 2048.

问题描述:随机生成 MN 和NK 的两个矩阵 A,B,对这两个矩阵做乘法得到矩阵 C.
输入:M , N, K 三个整数(512 ~2048)
输出:A,B,C 三个矩阵以及矩阵计算的时间

2.1.2.实现过程
这里可以选择点对点通信或者集合通信的方式实现,这里选择点对点方式,使用MPI_Send、MPI_Recv函数进行进程通信。
思想:

最简单的实现,按行并行:
主进程不参与计算,只负责分发和收集数据。在主进程中,A根据处理器数按行划分为大致相等的N部分,然后将部分的A和全部的B传递给子进程。子进程计算部分乘法并返回结果,主进程收集并整合报告结果。使用最简单的Send和Recv进行通信。

2.1.3.核心代码
①矩阵生成

void Gen_Matrix(int m,int n,int k){
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            A[i][j] = rand()%5;
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<k;j++){
            B[i][j] = rand()%5;
        }
    }
}

②MPI初始化
在这里插入图片描述

③获得进程数(通过bash)
在这里插入图片描述

④获得时间
在这里插入图片描述

⑤主处理器
在这里插入图片描述
这里主处理器通过Send传递给每一个处理器n/pnum行A、与整个的B,接着接受所有子处理器返回的结果进行拼接。

⑥子处理器
在这里插入图片描述
这里子处理器需要相应的接受Recv主处理器Send的过来的A部分行与整个的B,接着进行计算,即matMulti函数,最后Send回结果。

⑦矩阵乘法
请添加图片描述

这里就是简单的使用朴素计算方法,为了方便,直接将结果存在了部分结果矩阵返回。

2.2.通用矩阵乘法优化

2.2.1.问题描述
分别采用 MPI 点对点通信和 MPI 集合通信实现矩阵乘法中的进程之间通信,并比较两种实现方式的性能。
上面已经采用点对点通信的方式进行了实现,接下来针对集合通信来进行实验。

2.2.2.实现过程
这里分发A时,是将A平均的分配给了各个进程,使用Scatter分发比较何时,而B要完整的分发给所有处理器,所以使用Broadcast通信更为方便,收集计算结果使用Gather。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

广播是最简单但也是最有用的集体操作之一。
改用Scatter分配数据后,每个进程分配的部分矩阵具有完全相等的规模。因此。记comm_sz为进程数,矩阵的维度需要是comm_sz的倍数。我们将矩阵的维度扩展到comm_sz的倍数,多余的部分用0填充,保证正确性。
改用Scatter分配数据后,计算任务平均地分配给每一个进程,所以主进程不仅要分发收集结果,也要参与计算。如果分发的行数不够,就不能保证结果正确;如果分发的行数超出,就会出现很多不同类型的内存错误(大多都源于free时内存泄漏等原因)。

2.2.3.核心代码
①给A、B矩阵赋初值
在这里插入图片描述
这里必须要平均分配给各个处理器,因此有必要在不够分配时扩大矩阵,就需要在无数据的位置补零。

②获取矩阵大小,这里需要假设矩阵大小相同(通过bash)
在这里插入图片描述
在这里插入图片描述
后续处理,将真实矩阵大小扩展到处理器个数的倍数。

③MPI初始化
同上第一部分;

④主线程
在这里插入图片描述
在这里插入图片描述
主线程额外进行初始化矩阵以及计算并输出时间的工作
在这里插入图片描述
使用Scatter平均分发A的行,Bcast分发B。
在这里插入图片描述
使用Gather收集结果。

⑤所有处理器计算
在这里插入图片描述

MatMulti函数与上面实验相同。

2.3.改造实验1成矩阵乘法库函数

2.3.1.问题描述
将Lab1 的矩阵乘法改造为一个标准的库函数 matrix_multiply(函数实现文件和函数头文件),输入参数为三个完整定义矩阵(A,B,C),定义方式没有具体要求,可以是二维矩阵,也可以是 struct 等。在 Linux 系统中将此函数编译为.so 文件,由其他程序调用。

2.3.2.实验过程
通常情况下,对函数库的链接是放在编译时期(compile)完成的。所有相关的对象文件(object file)与牵涉到的函数库(library)被链接合成一个可执行文件(executable file)。程序在运行时,与函数库再无关系,因为所有需要的函数已拷贝到自己门下。所以这些函数库被称为静态库(static libaray),通常文件名为“libxxx.a”的形式。
由于动态链接库函数的共享特性,它们不会被拷贝到可执行文件中。在编译的时候,编译器只会做一些函数名之类的检查。在程序运行的时候,被调用的动态链接库函数被安置在内存的某个地方,所有调用它的程序将指向这个代码段。因此,这些代码必须使用相对地址,而不是绝对地址。在编译的时候,我们需要告诉编译器,这些对象文件是用来做动态链接库的,所以要用地址无关代码(Position Independent Code (PIC))。
对gcc编译器,只需添加上 -fPIC 标签,如:=

gcc -fPIC -c file1.c
gcc -fPIC -c file2.c
gcc -shared libxxx.so file1.o file2.o

注意到最后一行,-shared 标签告诉编译器这是要建立动态链接库。这与静态链接库的建立很不一样,后者用的是 ar 命令。也注意到,动态链接库的名字形式为 “libxxx.so” 后缀名为 “.so”

2.3.3.核心代码
①Mat_mul.h头文件
在这里插入图片描述

这里自定义矩阵,包括行、列、矩阵体,同时声明需要的函数。

②Mat_mul.c头文件
在这里插入图片描述

Malloc_matrix函数用于根据矩阵rows\cols分配矩阵并进行初始化。
在这里插入图片描述

Free_matrix函数用于释放相应空间。
在这里插入图片描述

Mul_matrix函数是核心计算函数,会首先检查是否满足乘法条件。

3.实验结果

3.1.通过MPI实现通用矩阵乘法

、

编译得到相应的MPI程序;
在这里插入图片描述

执行得到2048大小的矩阵使用2个处理器时间消耗为186s
在这里插入图片描述

执行得到2048大小的矩阵使用4个处理器时间消耗为75s
结果可以看出在处理器足够的情况下,增加处理器数目可以大大提高运算速度,符合预期。

3.2.基于MPI的通用矩阵乘法优化

编译程序:
在这里插入图片描述
在这里插入图片描述

执行得到2048大小的矩阵使用4个处理器时间消耗为87s,2048大小的矩阵使用2个处理器时间消耗为140s。
结果可以看出在处理器足够的情况下,增加处理器数目可以大大提高运算速度,符合预期。

3.3.改造实验1成矩阵乘法库函数

在这里插入图片描述

编译为.so文件
在这里插入图片描述

改变当前动态库路径为当前目录
在这里插入图片描述

编写的测试文件;
测试结果:
在这里插入图片描述

查看链接:
在这里插入图片描述
自己的.so文件成功链接。

4.实验感想

本次实验是高性能实验的核心,主要是使用MPI进行矩阵乘法的实现与优化,总体来说并不是很难,需要掌握点对点与集群通信两种方式的MPI。
其中还有很多可以优化的点,比如传递给处理器的整个的B是没有必要的,我们可以简单的对B矩阵进行转置,接着把与传递A相同的几行传递给处理器即可,可以大大减少通信量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

高性能计算实验——矩阵乘法基于MPI的并行实现及优化 的相关文章

  • 从多个 MPI 输出组成 VTK 文件

    对于盖驱动腔 CFD 的格子玻尔兹曼模拟 我将立方域分解为 也是立方 8 个子域 这些子域按 8 个等级独立计算 每个 MPI 等级都会为每个时间步生成一个 VTK 文件 并且由于我使用的是 ParaView 所以我希望将整个事物可视化为一
  • MPI 派生类型发送

    我尝试将派生类型发送到处理器 该类型包含来自其他派生类型的对象 我从开始这个例子示例 结构派生数据类型 https computing llnl gov tutorials mpi Derived Data Types 我添加我的代码 代码
  • 错误:libtool - 编译 MPI 程序时

    我在用着OpenSuse Leap我安装了openMPIYaST 心想 运行一个which mpirun我得到的命令 usr lib64 mpi gcc openmpi bin mpirun和跑步which mpicc i get usr
  • 居委会集体——减少运营

    我需要 allreduce MPI Ineighbor allreduce 来进行 MPI 中的集体通信 遗憾的是它尚未包含在内 明显但效率不高的解决方案是使用 MPI Neighbor alltoall 以增加缓冲区大小为代价 您有什么建
  • 在 C++ 中使用 MPI 对数组进行排序

    我想使用 MPI 库对随机数数组进行排序 这个想法是使用 MPI Scatterv 切割数组并将其发送到进程 每个进程都应该在本地对其数据量进行排序并将其发送回主进程 MPI Gatherv 主进程应该对部分排序的表进行排序 合并 如果最后
  • mpi 中的 darray 和 subarray 有什么区别?

    我有一个用于并行编程类的并行 I O 项目 并且我必须实现派生数据类型 我不太清楚darray和subarray之间的区别 darray 是否可以从动态分配的数组派生 主要区别是什么 子数组可让您描述较大多维数组的单个块 切片 如果每个 M
  • 除了snow SOCK之外的集群并行计算

    最近 R2 14 中添加的对并行计算的直接支持在我脑海中引发了一个问题 在 R 中创建集群有很多选项 我使用snow定期进行SOCK集群 但我知道还有其他方式 例如MPI 我用的是SOCKsnow集群 因为我不需要安装任何额外的软件 我使用
  • MPI - 异步广播/收集

    我有一个项目 需要 n 个进程才能工作 直到问题得到解决 每个从属进程执行相同的代码 当某种情况出现时 该进程需要以非阻塞的方式通知所有其他进程 其他进程也需要以非阻塞的方式接收这个消息 有没有办法不用线程单独的循环 我已经有一段时间没有使
  • 来自未知来源的 MPI 接收

    我正在 MPI 中实现一个程序 其中主进程 等级 0 应该能够接收来自其他进程的请求 这些进程要求只有根才知道的变量值 如果我按等级 0 进行 MPI Recv 我必须指定向根发送请求的进程的等级 但我无法控制它 因为进程不按顺序运行 1
  • 在 C++ 程序上使用 mpicc 链接失败

    我正在运行 Ubuntu 11 04 64 位 我已经安装了 OpenMPI 我正在尝试构建以下代码 这是 Gropp Lusk Skjellum 所著的 Using MPI 一书中测试问题的片段 include
  • 使用 mpi4py 接收多个发送命令

    如何修改以下代码 改编自http materials jeremybejarano com MPIwithPython pointToPoint html http materials jeremybejarano com MPIwithP
  • SLURM:如何在同一计算节点或不同节点上并行运行不同的可执行文件?

    Goal 了解如何通过 sbatch 作业提交来运行 共同调度或执行可执行文件 应用程序 使用 srun 或 mpirun 研究 代码片段 bin bash SBATCH job name LEBT SBATCH partition ang
  • MPI:广播 long long int

    这个程序估计Pi通过将随机 飞镖 采样点 扔到一个圆或半径 1内切于长度 2的方板内的圆上 利用关系 Area of circle Area of Square Pi 4 我们可以使用表示为的相同关系来估计 Pi Darts Inside
  • 使用 MPJ Express 发送对象

    我是并行编程的新手 我想用 java 来完成它 我想知道是否可以通过 MPI 发送和接收更复杂的对象 我用的是 MPJ Express 然而 每当我想发送一个对象时 我都会收到 ClassCastException MPI Init arg
  • 如何通过 mpi c++ 发送布尔数据类型?

    我是 C 新手 尝试通过 MPI 发送 bool 数据类型 但 C 不支持此数据类型 我试着做到了MPI BYTE and MPI INT但它什么也没打印 include
  • MPI_Type_create_subarray 和 MPI_Gather

    我必须解决一些 mpi 问题 我有 4 个从进程 每个进程都想发送一个 2d 子数组 CHUNK ROWS X CHUNK COLUMNS 到 master 0 Master 0 收集 ddd ROWS COLUMNS 中的所有块并打印它
  • MPI 矩阵向量乘法返回有时正确有时奇怪的值

    我有以下代码 Start MPI MPI Init argc argv int size atoi argv 1 int delta 10 int rnk int p int root 0 MPI Status mystatus MPI C
  • MPI+CUDA 与纯 MPI 相比有何优势?

    加速应用程序的常用方法是使用 MPI 或更高级别的库 例如在幕后使用 MPI 的 PETSc 并行化应用程序 然而 现在每个人似乎都对使用 CUDA 来并行化他们的应用程序或使用 MPI 和 CUDA 的混合来解决更雄心勃勃 更大的问题感兴
  • 无法使用 conda 安装 mpi4py 并指定预安装的 mpicc 路径

    我已经尝试安装mpi4py with env MPICC path to openmpi bin mpicc conda install c anaconda mpi4py 但我收到这样的消息 The following NEW packa
  • 了解多个进程的并发文件写入

    从这里 UNIX 中文件追加是原子的吗 https stackoverflow com questions 1154446 is file append atomic in unix 考虑多个进程打开同一个文件并向其追加内容的情况 O AP

随机推荐

  • 等响度曲线_什么是“响度”

    转自 https blog csdn net weixin 36225384 article details 112220422 原文 https www tonmeister ca wordpress 2014 06 07 bo tech
  • 正则表达式 匹配美元等多种货币符号的超简单方法

    p Sc 带小数点也不怕 Symbol Meaning p a character with the xx property Sc Currency symbol 方法二 暴力匹配 正则表达式 xA2 xA5 u058F u060B u09
  • QT开发之QString转换之路

    编程中少不了字符串的使用 QT提供了QString变量类型 字符串链表可直接使用QStringList进行变量定义和声明 那如果使用了其他表示字符串的变量应该怎么相互转化呢 这里就列举几个常用的几个类型之间的转化 错误之处 还望指出批评 1
  • 蓝桥杯2023模拟赛 滑行题目编号2414

    问题描述 小蓝准备在一个空旷的场地里面滑行 这个场地的高度不一 小蓝用一个 n 行 m 列的矩阵来表示场地 矩阵中的数值表示场地的高度 如果小蓝在某个位置 而他上 下 左 右中有一个位置的高度 严格 低于当前的高度 小蓝就可以滑过去 滑动距
  • 当你在浏览器中输入了网址访问时产生了哪些技术步骤

    当你在浏览器中输入了网址访问时产生了哪些技术步骤 前段时间在知乎上了看一些网络方面的知识 刚好小编自己也是从事这一块的相关工作由对网络方面有一定的了解 今天我们来讲讲 当你在浏览器中输入本站域名并回车后 这背后到底发生来什么事情 因平台原因
  • 如何让IE8及以下版本浏览器支持HTML5新的定义元素?

    如何让IE8及以下版本浏览器支持HTML5新的定义元素 1 我们都知道HTML5在HTML4的基础上 增加了很多新的特性和元素 其中也包括定义元素 比如 header section footer aside nav 但是这些元素在低版本的
  • 记一次个别网站不能访问的问题

    这是天猫的网站 之前我突然电脑不能访问这些网站 我试了很多种办法 都是失败 1 修改用户名 2 修改本地策略 3 后来又把浏览器 包括ie全部设置清除 4 还去选了下自动获取dns 最后我用cmd gt net int ip reset g
  • RuntimeError: CUDA error: CUBLAS_STATUS_EXECUTION_FAILED when calling `cublasSgemm( handle, opa, opb

    今天跑一个项目时遇到了如下问题 RuntimeError CUDA error CUBLAS STATUS EXECUTION FAILED when calling cublasSgemm handle opa opb m n k alp
  • 【GUI】LVGL8内存泄漏分析

    LVGL版本 V8 0 2 平台 ESP32S3 在调试过程中 发现有两个界面 在重复退出再进入时内存会不断增加的吃内存现象 然后做了分析和研究 1 样式style吃内存 在主页面 进入simple页面 再退出到主页面 再次进入simple
  • eNSP搭建USG6000V防火墙教程-web

    eNSP搭建USG6000V防火墙教程 web 1 先注册设备 很重要 一定要先注册设备 2 创建USG6000V 3 启动防火墙和连接客户机 3 开启一系列的功能和配置ip 4 避坑指南 1 先注册设备 很重要 一定要先注册设备 2 创建
  • vscode使用json后在浏览器报404not found

    user id 1 show 玲珑骰子安红豆 入骨相思知不知 name 王维 id 2 show 五花马 千金裘 name 李白 id 3 show 仰天大笑出门去 我辈岂是蓬蒿人 name 李白 list 王维 李白 如上是我写的json
  • c语言编程请增补函数fun

    题目 填空题 请增补函数fun 该函数的功能是 把从主函数中输入的字符串str2接在字符串str2的背面 例似 str2 How do str2 you do 结论输出 How do you do 试题程序 include include
  • 第十二届蓝桥杯国赛-H:和与乘积-python

    一 问题描述 二 问题分析 对于输入的一个数列 求这个数列的满足以下条件的区间个数 该区间的元素和与元素积相等 思路就是计算每一个区间的元素和与元素积 如果相等就计数加一 获取每个区间采用前缀和跟前缀积的方法 详见代码 注 这种方法也只能通
  • Sass语法学习

    1 编译监控 自动监控把sass编译成css文件 命令行 sass watch sass basic scss css basic css 在监控的sass后面 可以为 sass 生成 css 样式指定生成的格式 默认是nested型 st
  • 手机端网页:可拖拽悬浮按钮

    div style width 60px height 60px img src im div
  • cesium for unreal文档中的更新

    以前调试过cesium for unreal 再调试时一惊 发现api变了 静下心来思考流程 1 样本条要放在actor里 2 包含样本条的actor坐标放在原点 3 样本条坐标和法向量都要从经纬高到ue空间转换 变的只是api 所以深入了
  • 服务端架构:Mybatis-Plus的优缺点

    前段时间帮朋友处理java后端架构问题 看到了mybatis plus 其实早几年就知道这个东西 但一直没用没学 这两天许久未见的web服务看了看 聊聊个人感受 如有不适 请见谅 文章目录 优点 缺点 1 对数据访问层DAO的上层入侵太强
  • 死锁算法:银行家算法和安全性算法

    死锁算法 银行家算法和安全性算法 借鉴了一些文章 自己总结了一下 银行家算法 首先 算法的核心在于 每次进程申请资源时 都会进行一次试探性分配 若成功 则真实分配 基本思想 在每个新进程进入系统时 他必须声明在运行过程中 可能需要的每种资源
  • 多线程(重点)

    进程和线程的区别 1 根本区别 进程是操作系统进行资源分配的最小单元 线程是操作系统进行运算调度的最小单元 2 从属关系不同 进程中包含了线程 线程属于进程 3 开销不同 进程的创建 销毁和切换的开销都远大于线程 4 拥有资源不同 每个进程
  • 高性能计算实验——矩阵乘法基于MPI的并行实现及优化

    高性能计算实验 矩阵乘法基于MPI的并行实现及优化 1 实验目的 1 1 通过MPI实现通用矩阵乘法 1 2 基于MPI的通用矩阵乘法优化 1 3 改造实验1成矩阵乘法库函数 2 实验过程和核心代码 2 1 通过MPI实现通用矩阵乘法 2