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語言結(jié)構(gòu)體字節(jié)對齊的實現(xiàn)深入分析
這篇文章主要介紹了C語言結(jié)構(gòu)體字節(jié)對齊的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-10-10C++ 使用CRC32檢測內(nèi)存映像完整性的實現(xiàn)步驟
當我們使用動態(tài)補丁的時候,那么內(nèi)存中同樣不存在校驗效果,也就無法抵御對方動態(tài)修改機器碼了,為了防止解密者直接對內(nèi)存打補丁,我們需要在硬盤校驗的基礎(chǔ)上,增加內(nèi)存校驗,防止動態(tài)補丁的運用。2021-06-06如何解決C++未定義標識符 “string“、未定義標識符 “cout“、“name”:未知重寫說明
在C++編程中,未定義標識符"string"、"cout"錯誤多因缺少頭文件引入造成,而"name":未知重寫說明符錯誤則是未正確重寫基類成員函數(shù),解決未定義標識符錯誤需正確引入<string>和<iostream>頭文件,對于未知重寫說明符錯誤2024-09-09C語言使用stdlib.h庫函數(shù)的二分查找和快速排序的實現(xiàn)代碼
以下是對C語言使用stdlib.h庫函數(shù)的二分查找和快速排序的實現(xiàn)代碼進行了詳細的介紹,需要的朋友可以過來參考下。希望對大家有所幫助2013-10-10