MPI安装与程序设计

MPI

MPI(Message Passing Interface)是一种用于编写并行程序的标准和库,用于在分布式内存系统中进行消息传递和并行计算。MPI提供了一组函数和语义,用于在多个进程之间进行通信和同步,以实现并行计算和并行任务的协调。MPI在高性能计算领域被广泛应用,用于开发并行和分布式内存计算应用程序。它提供了丰富而强大的功能,使得开发者能够充分利用并行计算资源,提高计算效率和性能。MPI有很多种实现。MPICH是其中的MPI实现之一。

MPI安装

MPICH官网:https://www.mpich.org/downloads/
在这里插入图片描述

tar -zvxf mpich-4.1.2.tar.gz
cd mpich-4.1.2
./configure  --disable-fortran
make -j 10
sudo make install

在源码包的examples文件夹下有测试程序,可进行编译测试:

#include <stdio.h>
#include "mpi.h"int main(int argc, char *argv[])
{int rank;int size;MPI_Init(0, 0);MPI_Comm_rank(MPI_COMM_WORLD, &rank);MPI_Comm_size(MPI_COMM_WORLD, &size);printf("Hello world from process %d of %d\n", rank, size);MPI_Finalize();return 0;
}
mpicc  hellow.c  -o hellow
mpiexec -n 5 ./hellow

在这里插入图片描述

如果安装了anaconda,出现/home/fakerth/anaconda3/bin/mpicc: 行 323: x86_64-conda-linux-gnu-cc: 未找到命令,

在这里插入图片描述
使用conda deactivate退出anaconda环境,再进行编译。

MPI函数

1.MPI_Init:

函数原型:MPI_Init(int *argc, char ***argv)
功能:初始化MPI环境,必须在所有MPI函数之前调用。
参数:argc和argv是main函数的参数,用于传递命令行参数。
注意事项:每个进程都需要调用MPI_Init函数,通过MPI_COMM_WORLD通信域进行初始化。

2.MPI_Finalize:

函数原型:MPI_Finalize()
功能:终止MPI环境,必须在程序结束前调用。
注意事项:每个进程都需要调用MPI_Finalize函数,通过MPI_COMM_WORLD通信域进行终止。

3.MPI_Comm_size:

函数原型:MPI_Comm_size(MPI_Comm comm, int *size)
功能:获取指定通信域中的进程数量。
参数:comm是通信域,通常使用MPI_COMM_WORLD表示全局通信域;size是一个指针,返回通信域中的进程数量。

4.MPI_Comm_rank:

函数原型:MPI_Comm_rank(MPI_Comm comm, int *rank)
功能:获取当前进程在指定通信域中的进程ID(排名)。
参数:comm是通信域,通常使用MPI_COMM_WORLD表示全局通信域;rank是一个指针,返回当前进程在通信域中的进程ID。

5.MPI_Send:

函数原型:MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
功能:将数据发送给其他进程。
参数:buf是发送缓冲区的起始地址;count是发送的数据个数;datatype是发送的数据类型;dest是目标进程的ID;tag是消息标签;comm是通信域。

6.MPI_Recv:

函数原型:MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)
功能:接收来自其他进程发送的数据。
参数:buf是接收缓冲区的起始地址;count是接收的数据个数;datatype是接收的数据类型;source是源进程的ID;tag是消息标签;comm是通信域;status是一个结构体指针,用于返回接收消息的状态信息。

π的计算

在这里插入图片描述

#include <iostream>
#include "mpi.h"
using namespace std;int main(int argc, char**argv)
{//mpirun -np 4 calculatePI.o 800   其中的800是以参数的形式传入的,位于argv[1]long double pi=0, answer=0, PI=3.141592653589793238462643383279;int size, id, namelen,n=1000;double time;char processor_name[MPI_MAX_PROCESSOR_NAME];MPI_Status status;//如果参数列表中制定了n的值,则将该值赋给nif(argc==2)sscanf(argv[1], "%d", &n);MPI_Init(&argc, &argv);//开始计时time=MPI_Wtime();//获取进程信息MPI_Comm_size( MPI_COMM_WORLD , &size);MPI_Comm_rank( MPI_COMM_WORLD , &id);//比较n和size大小,若n过小,则返回if(n<size){cout<<"输入n值过小, 请重新输入"<<endl;MPI_Finalize();return 0;}for(int i=id; i<=n; i+=size){long double tempans;tempans = (long double)1/(long double)(2*i+1);if(i%2==0){answer+=tempans;}else{answer-=tempans;}}//如果是主进程if(id==0){long double recvbuf;pi=answer;for(int i=1; i<size; i++){MPI_Recv( &recvbuf , 1 , MPI_LONG_DOUBLE , MPI_ANY_SOURCE , 0 , MPI_COMM_WORLD , &status);pi+=recvbuf;}}else//发送消息并退出程序{MPI_Send( &answer , 1 , MPI_LONG_DOUBLE , 0 , 0 , MPI_COMM_WORLD);MPI_Finalize();return 0;}pi*=4;cout<<"主进程使用"<<MPI_Wtime()-time<<"秒, 最后得到PI的计算结果为: ";printf("%.20Lf\n",pi); cout<<"n = "<<n<<" 使用了 "<<MPI_Wtime()-time <<"s pi = ";printf("%.20Lf  %.20Lf \n",pi,abs(PI-pi)); MPI_Finalize();return 0;
}

C++用mpicxx编译,感受一个进程和八个进程的计算时间:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/292961.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# 跨越配置

跨越配置1 项目框架 .NET Framework 1.web.config配置 在system.webServer节点中添httpProtocol子节点 Access-Control-Allow-Origin值为“*”” <httpProtocol><customHeaders><add name"Access-Control-Allow-Origin" value"*" /><…

【Linux笔记】文件查看和编辑

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Linux学习 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 命令 cat (Concatenate and Display): more 和 less: nano 和 vim (文本编辑器): 结语 我的其他博客 前言 学习Linux命令行和文件…

通过几个基本概念说一下为什么openGauss是当下之选?

Database、Schema、User都是数据库的基本概念&#xff0c;SQL标准中也有明确规范。但不同数据库的具体实现也不尽相同&#xff0c;有些甚至大相径庭。这就导致用户在做国产化选型和数据库迁移时可能会遇到种种困难。本文从这几个基本概念展开&#xff0c;说说为什么openGauss系…

项目应用多级缓存示例

前不久做的一个项目&#xff0c;需要在前端实时展示硬件设备的数据。设备很多&#xff0c;并且每个设备的数据也很多&#xff0c;总之就是数据很多。同时&#xff0c;设备的刷新频率很快&#xff0c;需要每2秒读取一遍数据。 问题来了&#xff0c;我们如何读取数据&#xff0c…

.Net 访问电子邮箱-LumiSoft.Net,好用

序言: 网上找了很多关于.Net如何访问电子邮箱的方法,但是大多数都达不到想要的需求,只有一些 收发邮件。因此 花了很大功夫去看 LumiSoft.Net.dll 的源码,总算做出自己想要的结果了,果然学习诗人进步。 介绍: LumiSoft.Net.dll 是 C# 下的 免费开源 的关于网络 编程 的…

Bean生命周期源码(二)

书接上文 文章目录 一.、前文回顾二、 创建Bean之getBean方法 一.、前文回顾 在前面一部分中&#xff0c;我们分析了Spring底层是如何加载BeanDefinition以及是如何将BeanDefinition注册到容器中的。以及分析了部分非懒加载单例Bean的实例化的内容&#xff0c;包括合并beanDe…

Ubuntu 常用命令之 fdisk 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 fdisk 是一个用于处理磁盘分区的命令行工具&#xff0c;它在 Linux 系统中广泛使用。fdisk 命令可以创建、删除、更改、复制和显示硬盘分区&#xff0c;以及更改硬盘的分区 ID。 fdisk 命令的常用参数如下 -l&#xff1a;列出所…

μC/OS-III 里面的环形表

文章目录 1、时钟节拍任务2、定时器列表 μC/OS-III 里面两个地方用到了环形表&#xff0c;时钟节拍任务&#xff0c;定时器列表&#xff0c;通过排序后&#xff0c;效率是非常高的。 以下内容整理自 嵌入式实时操作系统uC/OS-Ⅲ 1、时钟节拍任务 2023/12/21 18:04:16 (1) 该…

养老院自助饮水机(字符设备驱动)

目录 1、项目背景 2、驱动程序 2.1 三层架构 2.2 驱动三要素 2.3 字符设备驱动 2.3.1 驱动模块 2.3.2 应用层 3、设计实现 3.1 项目设计 3.2 项目实现 3.2.1 驱动模块代码 3.2.2 用户层代码 4、功能特性 5、技术分析 6. 总结与未来展望 1、项目背景 养老院的老人…

虾皮广告怎么做:如何在虾皮平台上进行广告投放

在虾皮&#xff08;Shopee&#xff09;平台上进行广告投放可以帮助您提高产品的曝光度和销量。通过有针对性的广告&#xff0c;您可以在虾皮平台上吸引更多的潜在买家&#xff0c;提高产品的可见度并增加销售机会。本文将为您介绍在虾皮平台上创建和管理广告的一些建议&#xf…

JAVA版的鸿鹄云商B2B2C:多商家入驻直播商城系统特性解析 商城免 费搭建

鸿鹄云商 b2b2c产品概述 【b2b2c平台】&#xff0c;以传统电商行业为基石&#xff0c;鸿鹄云商支持“商家入驻平台自营”多运营模式&#xff0c;积极打造“全新市场&#xff0c;全新 模式”企业级b2b2c电商平台&#xff0c;致力干助力各行/互联网创业腾飞并获取更多的收益。从消…

K8s攻击案例:Privileged特权容器导致节点沦陷

01、概述 特权容器&#xff08;Privileged Container&#xff09;是一种比较特殊的容器&#xff0c;在K8s中运行特权容器&#xff0c;需要将 Privileged 设为 true &#xff0c;容器可以执行几乎所有可以直接在主机上执行的操作。 基于此&#xff0c;利用容器的特权配置可以获取…