返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++BoostMPI接口详细讲解
  • 646
分享到

C++BoostMPI接口详细讲解

C++BoostMPIC++MPI接口 2022-11-21 22:11:57 646人浏览 八月长安
摘要

目录一、说明二、开发和运行时环境三、简单数据交换一、说明 Boost.MPI 提供了 MPI 标准(消息传递接口)的接口。该标准简化了并发执行任务的程序的开发。您可以使用线程或通过共

一、说明

Boost.MPI 提供了 MPI 标准(消息传递接口)的接口。该标准简化了并发执行任务的程序的开发。您可以使用线程或通过共享内存或网络连接使多个进程相互通信来开发此类程序。 MPI 的优点是你不需要关心这些细节。您可以完全专注于并行化您的程序。

缺点是您需要 MPI 运行时环境。如果您控制运行时环境,MPI 只是一个选项。例如,如果你想分发一个可以通过双击启动的程序,你将无法使用 MPI。虽然操作系统开箱即用地支持线程、共享内存和网络,但它们通常不提供 MPI 运行时环境。用户需要执行额外的步骤来启动 MPI 程序。

  • 开发和运行时环境
  • 简单的数据交换
  • 异步数据交换
  • 集体数据交换

二、开发和运行时环境

MPI 定义了用于并行计算的函数。并行计算是指在支持任务并行执行的运行时环境中可以并发执行任务的程序。这样的运行时环境通常基于多个处理器。由于单个处理器只能顺序执行代码,因此链接多个处理器会创建一个可以并行执行任务的运行时环境。如果连接了数千个处理器,结果就是一台并行计算机——一种通常只在超级计算机中才能找到的架构。 MPI 来自于寻找更容易地为超级计算机编程的方法的搜索。

如果你想使用 MPI,你需要一个标准的实现。虽然 MPI 定义了许多功能,但它们通常不受开箱即用的操作系统支持。例如,windows 的桌面版本不附带 MPI 支持。

最重要的 MPI 实现是 MPICH 和 Open MPI。 MPICH 是最早的 MPI 实现之一。它自 1990 年代中期就已存在。 MPICH 是一种成熟且可移植的实现,并得到积极维护和更新。 Open MPI 的第一个版本于 2005 年发布。由于 Open MPI 是一项协作成果,其中包括许多负责早期 MPI 实现的开发人员,因此 Open MPI 被视为未来的标准。然而,这并不意味着可以忽略 MPICH。有几种基于 MPICH 的 MPI 实现。例如,Microsoft 发布了一个名为 Microsoft HPC Pack 的 MPI 实现,它基于 MPICH。

MPICH 为各种操作系统(如 Windows、linux 和 OS X)提供安装文件。如果您需要 MPI 实现并且不想从源代码构建它,MPICH 安装文件是开始使用 MPI 的最快途径。

MPICH 安装文件包含开发 MPI 程序所需的头文件和库。此外,它们还包含一个 MPI 运行时环境。因为 MPI 程序同时在多个处理器上执行任务,所以它们在多个进程中运行。一个 MPI 程序会启动多次,而不仅仅是一次。同一 MPI 程序的多个实例在多个处理器上运行,并通过 MPI 标准定义的函数进行通信。

您无法通过双击启动 MPI 程序。您使用一个帮助程序,通常称为 mpiexec。您将 MPI 程序传递给 mpiexec,它会在 MPI 运行时环境中启动您的程序。命令行选项确定启动了多少个进程以及它们如何通信——例如,通过套接字或共享内存。因为 MPI 运行时环境会处理这些细节,所以您可以专注于并行编程。

如果您决定使用 MPICH 的安装文件,请注意 MPICH 仅提供 64 位版本。您必须使用 64 位编译器通过 MPICH 开发 MPI 程序并构建 64 位版本的 Boost.MPI。

三、简单数据交换

Boost.MPI 是 MPI 标准的 c++ 接口。该库使用命名空间 boost::mpi。包含头文件 boost/mpi.hpp 就足以访问所有类和函数。

示例 47.1。 MPI 环境和通信器

#include <boost/mpi.hpp>
#include <iOStream>
int main(int arGC, char *argv[])
{
  boost::mpi::environment env{argc, argv};
  boost::mpi::communicator world;
  std::cout << world.rank() << ", " << world.size() << '\n';
}

Example47.1

示例 47.1 是一个简单的 MPI 程序。它使用两个类,您将在随后的所有示例中找到它们。 boost::mpi::environment 初始化 MPI。构造函数从 MPI 标准调用函数 MPI_Init()。析构函数调用 MPI_Finalize()。 boost::mpi::communicator 用于创建通信器。通信器是 MPI 的核心概念之一,支持进程之间的数据交换。

boost::mpi::environment 是一个非常简单的类,只提供了几个成员函数。您可以调用 initialized() 检查 MPI 是否已成功初始化。成员函数返回一个 bool 类型的值。 processor_name() 以 std::string 的形式返回当前进程的名称。 abort() 会停止 MPI 程序,而不仅仅是当前进程。您将一个 int 值传递给 abort()。该值将作为 MPI 程序的返回值传递到 MPI 运行时环境。对于大多数 MPI 程序,您不需要这些成员函数。您通常在程序开始时实例化 boost::mpi::environment,然后不使用该对象——如示例 47.1 和本章中的以下示例。

boost::mpi::communicator 更有趣。此类是一个通信器,它链接作为 MPI 程序一部分的进程。每个进程都有一个等级,它是一个整数——所有进程都会被枚举。进程可以通过在通信器上调用 rank() 来发现其等级。如果进程想知道有多少个进程,它会调用 size()。

要运行示例 47.1,您必须使用您正在使用的 MPI 实现提供的帮助程序。对于 MPICH,辅 助程序称为 mpiexec。您可以通过以下命令使用此帮助程序运行示例 47.1:

mpiexec-n4sample.exe

mpiexec 需要一个 MPI 程序的名称和一个告诉它要启动多少进程的选项。选项 -n 4 告诉 mpiexec 启动四个进程。因此 MPI 程序启动了四次。但是,这四个过程并不是独立的。它们通过 MPI 运行时环境链接,并且它们都属于同一个通信器,这给每个进程一个等级。如果您使用四个进程运行示例 47.1,rank() 返回一个从 0 到 3 的数字和 size() 4。

请注意,输出可能会混淆。毕竟,有四个进程同时写入标准输出流。例如,不知道排名为 0 或任何其他排名的进程是否是第一个写入标准输出流的进程。也有可能一个进程在写入标准输出流时会中断另一个进程。在另一个进程写入标准输出流之前,被中断的进程可能无法完成写入其等级和通信器的大小,从而破坏输出。

示例 47.2。发送和接收数据的阻塞函数

#include <boost/mpi.hpp>
#include <iostream>
int main(int argc, char *argv[])
{
  boost::mpi::environment env{argc, argv};
  boost::mpi::communicator world;
  if (world.rank() == 0)
  {
    int i;
    world.recv(1, 16, i);
    std::cout << i << '\n';
  }
  else if (world.rank() == 1)
  {
    world.send(0, 16, 99);
  }
}

boost::mpi::communicator 提供了两个简单的成员函数,send() 和 recv(),用于在两个进程之间交换数据。它们是阻塞函数,仅在发送或接收数据时才返回。这对于 recv() 尤其重要。如果在没有其他进程向其发送数据的情况下调用 recv(),调用将阻塞并且进程将在调用中停止。

在示例 47.2 中,等级为 0 的进程使用 recv() 接收数据。等级为 1 的进程使用 send() 发送数据。如果你用两个以上的进程启动程序,其他进程什么都不做就直接退出。

您将三个参数传递给 send():第一个参数是数据应发送到的进程的等级。第二个参数是用于识别数据的标签。第三个参数是数据。

标签始终是一个整数。在示例 47.2 中,标签是 16。标签可以识别对 send() 的调用。您会看到该标签与 recv() 一起使用。

传递给 send() 的第三个参数是 99。这个数字从等级 1 的进程发送到等级 0 的进程。Boost.MPI 支持所有原始类型。可以直接发送像 99 这样的 int 值。

recv() 需要类似的参数。第一个参数是应该从中接收数据的进程的等级。第二个参数是将对 recv() 的调用与对 send() 的调用链接起来的标签。第三个参数是存放接收到的数据的变量。

如果您使用至少两个进程运行示例 47.2,则会显示 99。

示例 47.3。从任何进程接收数据

#include <boost/mpi.hpp>
#include <iostream>
int main(int argc, char *argv[])
{
  boost::mpi::environment env{argc, argv};
  boost::mpi::communicator world;
  if (world.rank() == 0)
  {
    int i;
    world.recv(boost::mpi::any_source, 16, i);
    std::cout << i << '\n';
  }
  else
  {
    world.send(0, 16, world.rank());
  }
}

Example47.3

示例 47.3 基于示例 47.2。它不发送数字 99,而是发送调用 send() 的进程的等级。这可以是等级大于 0 的任何进程。

对等级为 0 的进程的 recv() 调用也发生了变化。 boost::mpi::any_source 是第一个参数。这意味着对 recv() 的调用将接受来自任何发送带有标签 16 的数据的进程的数据。

如果您使用两个进程启动示例 47.3,将显示 1。毕竟,只有一个进程可以调用 send()——rank 为 1 的进程。如果你启动程序时有两个以上的进程,不知道会显示哪个数字。在这种情况下,多个进程将调用 send() 并尝试发送它们的排名。哪个进程最先,因此显示哪个排名是随机的。

示例 47.4。使用 boost::mpi::status 检测发件人

#include <boost/mpi.hpp>
#include <iostream>
int main(int argc, char *argv[])
{
  boost::mpi::environment env{argc, argv};
  boost::mpi::communicator world;
  if (world.rank() == 0)
  {
    int i;
    boost::mpi::status s = world.recv(boost::mpi::any_source, 16, i);
    std::cout << s.source() << ": " << i << '\n';
  }
  else
  {
    world.send(0, 16, 99);
  }
}

recv() 的返回值类型为 boost::mpi::status。此类提供了一个成员函数 source(),它返回从中接收数据的进程的等级。示例 47.4 告诉您数字 99 是从哪个进程收到的。

到目前为止,所有示例都使用 send() 和 recv() 来传输 int 值。在示例 47.5 中,传输了一个字符串

示例 47.5。使用 send() 和 recv() 传输数组

#include <boost/mpi.hpp>
#include <iostream>
int main(int argc, char *argv[])
{
  boost::mpi::environment env{argc, argv};
  boost::mpi::communicator world;
  if (world.rank() == 0)
  {
    char buffer[14];
    world.recv(boost::mpi::any_source, 16, buffer, 13);
    buffer[13] = '\0';
    std::cout << buffer << '\n';
  }
  else
  {
    const char *c = "Hello, world!";
    world.send(0, 16, c, 13);
  }
}

send() 和 recv() 可以传输数组和单个值。示例 47.5 传输字符数组中的字符串。因为 send() 和 recv() 支持像 char 这样的基本类型,所以可以毫无问题地传输 char 数组。

send() 将指向字符串的指针作为其第三个参数,并将字符串的大小作为其第四个参数。传递给 recv() 的第三个参数是指向存储接收数据的数组的指针。第四个参数告诉 recv() 应该接收多少个字符并将其存储在缓冲区中。示例 47.5 写出 Hello, world!到标准输出流。

示例 47.6。使用 send() 和 recv() 传输字符串

#include <boost/mpi.hpp>
#include <boost/serialization/string.hpp>
#include <string>
#include <iostream>
int main(int argc, char *argv[])
{
  boost::mpi::environment env{argc, argv};
  boost::mpi::communicator world;
  if (world.rank() == 0)
  {
    std::string s;
    world.recv(boost::mpi::any_source, 16, s);
    std::cout << s << '\n';
  }
  else
  {
    std::string s = "Hello, world!";
    world.send(0, 16, s);
  }
}

尽管 Boost.MPI 只支持原始类型,但这并不意味着它不能传输非原始类型的对象。 Boost.MPI 与 Boost.Serialization 一起工作。可以根据 Boost.Serialization 规则序列化的对象可以使用 Boost.MPI 进行传输。

示例 47.6 传输“Hello, world!”这次传输的值不是字符数组,而是 std::string。 Boost.Serialization 提供头文件 boost/serialization/string.hpp,只需要包含它以使 std::string 可序列化。

到此这篇关于C++ Boost MPI接口详细讲解的文章就介绍到这了,更多相关C++ Boost MPI内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++BoostMPI接口详细讲解

本文链接: https://lsjlt.com/news/173292.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++BoostMPI接口详细讲解
    目录一、说明二、开发和运行时环境三、简单数据交换一、说明 Boost.MPI 提供了 MPI 标准(消息传递接口)的接口。该标准简化了并发执行任务的程序的开发。您可以使用线程或通过共...
    99+
    2022-11-21
    C++ Boost MPI C++ MPI接口
  • Java超详细透彻讲解接口
    目录一、引入二、理解三、使用四、应用-代理模式(Proxy)1. 应用场景2. 分类3. 代码演示五、接口和抽象类之间的对比六、经典题目(排错)一、引入 一方面,有时必须从几个类中派...
    99+
    2024-04-02
  • C++ Cartographer的入口nodemain详细讲解
    目录Run函数读取配置参数构建地图构建器Node类的初始化开始轨迹与结束轨迹啃一下谷歌优秀的激光SLAM开源框架-Cartographer. 这个框架算法简单,但是程序部分太多需要学...
    99+
    2023-03-19
    C++ node main C++ Cartographer
  • Spring详细讲解FactoryBean接口的使用
    目录一、基本使用二、高级使用FactoryBean是一个接口,创建对象的过程使用了工厂模式。 一、基本使用 让Spring容器通过FactoryBean来实现对象的创建。 创建Fa...
    99+
    2024-04-02
  • C++BoostAtomic详细讲解
    目录一、说明二、示例和代码一、说明 Boost.Atomic 提供类 boost::atomic,可用于创建原子变量。它们被称为原子变量,因为所有访问都是原子的。 Boost.Ato...
    99+
    2022-11-21
    C++ Boost Atomic C++ Atomic
  • C语言 超详细讲解链接器
    目录1 什么是链接器2 声明与定义3 命名冲突3.1 命名冲突3.2 static修饰符4 形参、实参、返回值5 检查外部类型6 头文件1 什么是链接器 典型的链接器把由编译器或汇编...
    99+
    2024-04-02
  • C++BoostUuid超详细讲解
    目录一、说明二、Boost.Uuid库示例和代码一、说明 Boost.Uuid 为 UUID 提供生成器。 UUID 是不依赖于中央协调实例的通用唯一标识符。例如,没有数据库存储所有...
    99+
    2022-12-08
    C++ Boost Uuid C++ Uuid标识符
  • C++BoostUtility超详细讲解
    目录一、说明二、Boost.Utility库示例和代码一、说明 Boost.Utility 库是杂项、有用的类和函数的集合,它们太小而无法在独立库中维护。虽然实用程序很小并且可以快速...
    99+
    2022-12-08
    C++ Boost Utility C++ Utility库
  • Vue项目中接口调用的详细讲解
    在企业开发过程中,往往有着明确的前后端的分工,前端负责接收、使用接口,后端负责编写、处理接口。 对于前端如何使用接口,今天在Vue中进行讲解。 一个项目往往由这几个部分组成。 其中...
    99+
    2024-04-02
  • Java迭代器与Collection接口超详细讲解
    目录关于迭代器你都知道什么什么是迭代器迭代器的4个API如何使用迭代器?Collection集合接口知多少为什么不使用数组而是集合Collection接口的API都有什么Abstra...
    99+
    2024-04-02
  • Java超详细讲解接口的实现与用法
    目录1.接口的定义2.接口的实现3.接口的引用4.接口的继承5.利用接口实现多重继承1.接口的定义 接口是一种特殊的抽象类,是Java提供的一个重要的功能,与抽象类不同的是: 接口的...
    99+
    2024-04-02
  • JavaFeign微服务接口调用方法详细讲解
    目录Feign说明引入依赖启动类开启客户端Feign接口开发编写容错类在业务层调用Feign客户端接口Feign的常用属性如下Feign说明 Feign是一种声明式、模板化的HTTP...
    99+
    2023-01-29
    Java Feign微服务接口调用 Java Feign微服务调用
  • C# 多线程详细讲解
    多线程是指在一个程序中同时执行多个线程,每个线程可以独立执行不同的任务。在 C# 中,可以使用 System.Threading 命...
    99+
    2023-09-09
    C#
  • C++ Boost Assign超详细讲解
    目录说明Exercise说明 Boost.Assign Boost.Assign 库提供了帮助函数来初始化容器或向容器添加元素。如果需要将许多元素存储在一个容器中,这些函数尤其有用。...
    99+
    2022-12-09
    C++ Boost Assign C++ Assign库
  • C++超详细讲解泛型
    目录1.了解泛型编程2.函数模板2.1简单示例2.2多个模板参数2.3模板实例化2.4模板和普通函数同时存在2.5函数模板不支持定义和声明分离3.类模板3.1简单示例3.2成员函数声...
    99+
    2024-04-02
  • C++BoostTokenizer使用详细讲解
    目录介绍示例一示例二示例三示例四示例五示例六示例七介绍 库 Boost.Tokenizer 允许您通过将某些字符解释为分隔符来迭代字符串中的部分表达式。使用 boost::token...
    99+
    2022-11-16
    C++ Boost Tokenizer C++ Boost Tokenizer功能与使用
  • C++ pimpl机制详细讲解
    目录什么是PImpl机制为什么用PImpl 机制PImpl实现方法一方法二PImpl 缺点总结源码仓库 什么是PImpl机制 Pointer to implementation(PI...
    99+
    2022-11-13
    C++ pimpl 机制 C++ pimpl模式
  • C++BoostBimap示例详细讲解
    目录一、提要二、示例练习一、提要 库 Boost.Bimap 基于 Boost.MultiIndex 并提供了一个无需先定义即可立即使用的容器。该容器类似于 std::map,但支持...
    99+
    2022-11-13
    C++ Boost Bimap C++ Bimap库
  • Java超详细讲解抽象类与接口的使用
    目录一、抽象类1、抽象类的语法2、抽象类的特性3、抽象类的作用二、接口1、接口的概念2、接口使用3、接口特性4、实现多个接口5、接口间的继承6、常用的接口(1)Comparable接...
    99+
    2024-04-02
  • C#接口编程详细降级
    这篇文章主要介绍“C#接口编程详细降级”,在日常操作中,相信很多人在C#接口编程详细降级问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C#接口编程详细降级”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!接口...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作