C++進程鏈接工具之通信器詳解
一、傳播者
本章中的所有示例僅使用一個連接所有進程的通信器。但是,可以創(chuàng)建更多的通信器來鏈接進程的子集。這對于不需要由所有進程執(zhí)行的集體操作特別有用。
二、示例和代碼
示例 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';
}示例 47.15 使用函數(shù) boost::mpi::broadcast()。此函數(shù)發(fā)送字符串“Hello, world!”從等級為 0 的進程到鏈接到本地??通信器的所有進程。等級為 0 的進程也必須鏈接到該通信器。
本地通信器是通過調(diào)用 split() 創(chuàng)建的。 split() 是在全局通信器世界上調(diào)用的成員函數(shù)。 split() 需要一個整數(shù)來將進程鏈接在一起。將相同整數(shù)傳遞給 split() 的所有進程都鏈接到相同的通信器。傳遞給 split() 的整數(shù)值無關(guān)緊要。重要的是應(yīng)該由特定通信器鏈接的所有進程都傳遞相同的值。
在示例 47.15 中,等級為 0 和 1 的兩個進程將 99 傳遞給 split()。如果程序啟動時有兩個以上的進程,則額外的進程會傳遞 100。這意味著前兩個進程有一個本地通信器,所有其他進程都有另一個本地通信器。每個進程都鏈接到 split() 返回的通信器。是否有其他進程鏈接到同一個通信器取決于其他進程是否將相同的整數(shù)傳遞給 split()。
請注意,等級始終與傳播者有關(guān)。最低等級始終為 0。在示例 47.15 中,相對于全局通信器具有等級 0 的進程相對于其本地通信器也具有等級 0。相對于全局通信器具有等級 2 的進程相對于其本地通信器具有等級 0。
如果您使用兩個或更多進程啟動示例 47.15,您好,世界!將顯示兩次 - 每次由相對于全局通信器的等級為 0 和 1 的進程顯示一次。因為 s 設(shè)置為“Hello, world!”僅在全局等級為 0 的進程中,此字符串僅通過通信器發(fā)送到鏈接到同一通信器的那些進程。這只是具有全局排名 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 的幫助下完成的。如果您在通信器上調(diào)用成員函數(shù) group(),則鏈接到通信器的所有進程都將在類型為 boost::mpi::group 的對象中返回。您不能使用此對象進行通信。它只能用于形成一組新的進程,然后可以從中創(chuàng)建通信器。
boost::mpi::group 提供成員函數(shù),如 include() 和 exclude()。您傳遞迭代器以包含或排除進程。 include() 和 exclude() 返回一個類型為 boost::mpi::group 的新組。
示例 47.16 將兩個迭代器傳遞給 exclude(),它們引用類型為 boost::integer_range 的對象。該對象表示一個整數(shù)范圍。它是在函數(shù) boost::irange() 的幫助下創(chuàng)建的,它需要一個下限和上限。上限是一個不屬于該范圍的整數(shù)。在此示例中,這意味著 r 僅包含整數(shù) 0。
調(diào)用 exclude() 會導(dǎo)致創(chuàng)建子組,其中包含除等級為 0 的進程之外的所有進程。然后使用該組創(chuàng)建一個新的通信器 others。這是通過將全局通信器世界和子組傳遞給 boost::mpi::communicator 的構(gòu)造函數(shù)來完成的。
請注意,others 是一個 communicator,它在 rank 0 的進程中是空的。rank 0 的進程沒有鏈接到這個 communicator,但是變量 others 仍然存在于這個進程中。您必須注意不要在此過程中使用其他人。示例 47.16 通過在子組上調(diào)用 rank() 來防止這種情況。成員函數(shù)在不屬于該組的進程中返回一個類型為 boost::optional 的空對象。其他進程接收它們相對于該組的等級。
如果 rank() 返回排名并且沒有類型為 boost::optional 的空對象,則調(diào)用 boost::mpi::broadcast()。等級為 0 的進程發(fā)送字符串“Hello, world!”鏈接到其他通信器的所有進程。請注意,等級是相對于那個傳播者的。相對于其他進程排名為 0 的進程相對于全球通信者世界排名為 1。
如果您使用兩個以上的進程運行示例 47.16,則全局等級大于 0 的所有進程都將顯示 Hello, world!。
到此這篇關(guān)于C++進程鏈接工具之通信器詳解的文章就介紹到這了,更多相關(guān)C++通信器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++異步操作future和aysnc與function和bind
這篇文章主要介紹了C++異步操作future和aysnc與function和bind,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09
C++?構(gòu)造函數(shù)學(xué)習(xí)筆記
這篇文章主要為大家介紹了C++?構(gòu)造函數(shù)學(xué)習(xí)筆記,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-10-10

