網站首頁 編程語言 正文
一、傳播者
本章中的所有示例僅使用一個連接所有進程的通信器。但是,可以創建更多的通信器來鏈接進程的子集。這對于不需要由所有進程執行的集體操作特別有用。
二、示例和代碼
示例 47.15。使用多個通信器
#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;
boost::mpi::communicator local = world.split(world.rank() < 2 ? 99 : 100);
std::string s;
if (world.rank() == 0)
s = "Hello, world!";
boost::mpi::broadcast(local, s, 0);
std::cout << world.rank() << ": " << s << '\n';
}
Example47.15
示例 47.15 使用函數 boost::mpi::broadcast()。此函數發送字符串“Hello, world!”從等級為 0 的進程到鏈接到本地??通信器的所有進程。等級為 0 的進程也必須鏈接到該通信器。
本地通信器是通過調用 split() 創建的。 split() 是在全局通信器世界上調用的成員函數。 split() 需要一個整數來將進程鏈接在一起。將相同整數傳遞給 split() 的所有進程都鏈接到相同的通信器。傳遞給 split() 的整數值無關緊要。重要的是應該由特定通信器鏈接的所有進程都傳遞相同的值。
在示例 47.15 中,等級為 0 和 1 的兩個進程將 99 傳遞給 split()。如果程序啟動時有兩個以上的進程,則額外的進程會傳遞 100。這意味著前兩個進程有一個本地通信器,所有其他進程都有另一個本地通信器。每個進程都鏈接到 split() 返回的通信器。是否有其他進程鏈接到同一個通信器取決于其他進程是否將相同的整數傳遞給 split()。
請注意,等級始終與傳播者有關。最低等級始終為 0。在示例 47.15 中,相對于全局通信器具有等級 0 的進程相對于其本地通信器也具有等級 0。相對于全局通信器具有等級 2 的進程相對于其本地通信器具有等級 0。
如果您使用兩個或更多進程啟動示例 47.15,您好,世界!將顯示兩次 - 每次由相對于全局通信器的等級為 0 和 1 的進程顯示一次。因為 s 設置為“Hello, world!”僅在全局等級為 0 的進程中,此字符串僅通過通信器發送到鏈接到同一通信器的那些進程。這只是具有全局排名 1 的進程,這是唯一將 99 傳遞給 split() 的其他進程。
示例 47.16。使用組對流程進行分組
#include <boost/mpi.hpp>
#include <boost/serialization/string.hpp>
#include <boost/range/irange.hpp>
#include <boost/optional.hpp>
#include <string>
#include <iostream>
int main(int argc, char *argv[])
{
boost::mpi::environment env{argc, argv};
boost::mpi::communicator world;
boost::mpi::group local = world.group();
boost::integer_range<int> r = boost::irange(0, 1);
boost::mpi::group subgroup = local.exclude(r.begin(), r.end());
boost::mpi::communicator others{world, subgroup};
std::string s;
boost::optional<int> rank = subgroup.rank();
if (rank)
{
if (rank == 0)
s = "Hello, world!";
boost::mpi::broadcast(others, s, 0);
}
std::cout << world.rank() << ": " << s << '\n';
}
MPI 支持分組進程。這是在類 boost::mpi::group 的幫助下完成的。如果您在通信器上調用成員函數 group(),則鏈接到通信器的所有進程都將在類型為 boost::mpi::group 的對象中返回。您不能使用此對象進行通信。它只能用于形成一組新的進程,然后可以從中創建通信器。
boost::mpi::group 提供成員函數,如 include() 和 exclude()。您傳遞迭代器以包含或排除進程。 include() 和 exclude() 返回一個類型為 boost::mpi::group 的新組。
示例 47.16 將兩個迭代器傳遞給 exclude(),它們引用類型為 boost::integer_range 的對象。該對象表示一個整數范圍。它是在函數 boost::irange() 的幫助下創建的,它需要一個下限和上限。上限是一個不屬于該范圍的整數。在此示例中,這意味著 r 僅包含整數 0。
調用 exclude() 會導致創建子組,其中包含除等級為 0 的進程之外的所有進程。然后使用該組創建一個新的通信器 others。這是通過將全局通信器世界和子組傳遞給 boost::mpi::communicator 的構造函數來完成的。
請注意,others 是一個 communicator,它在 rank 0 的進程中是空的。rank 0 的進程沒有鏈接到這個 communicator,但是變量 others 仍然存在于這個進程中。您必須注意不要在此過程中使用其他人。示例 47.16 通過在子組上調用 rank() 來防止這種情況。成員函數在不屬于該組的進程中返回一個類型為 boost::optional 的空對象。其他進程接收它們相對于該組的等級。
如果 rank() 返回排名并且沒有類型為 boost::optional 的空對象,則調用 boost::mpi::broadcast()。等級為 0 的進程發送字符串“Hello, world!”鏈接到其他通信器的所有進程。請注意,等級是相對于那個傳播者的。相對于其他進程排名為 0 的進程相對于全球通信者世界排名為 1。
如果您使用兩個以上的進程運行示例 47.16,則全局等級大于 0 的所有進程都將顯示 Hello, world!。
原文鏈接:https://yamagota.blog.csdn.net/article/details/127942024
相關推薦
- 2022-05-10 詳解CLR的內存分配和回收機制_C#教程
- 2022-08-28 shell腳本之sed詳細用法詳解_linux shell
- 2022-04-20 從0編寫區塊鏈之用python解釋區塊鏈最基本原理_python
- 2022-07-04 Python自動化辦公之清理重復文件詳解_python
- 2023-01-03 Qt學習之容器類的使用教程詳解_C 語言
- 2022-10-14 SpringCloud組件之Gateway微服務網關
- 2022-02-19 AttributeError: ‘str‘ object has no attribute ‘dec
- 2022-04-18 taro 中設計稿尺寸相關問題,以及自適應頁面寫法
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支