<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
到目前為止介紹的功能共用一對一的關係:即一個程序傳送和一個程序接收。連結是通過標籤建立的。本節介紹在多個程序中呼叫相同引數但執行不同操作的函數。對於一個程序,函數可能會傳送資料,對於另一個程序,它可能會接收資料。這些功能稱為集體操作。
範例 47.9。使用 gather() 從多個程序接收資料
#include <boost/mpi.hpp> #include <boost/serialization/string.hpp> #include <vector> #include <string> #include <iterator> #include <algorithm> #include <iostream> int main(int argc, char *argv[]) { boost::mpi::environment env{argc, argv}; boost::mpi::communicator world; if (world.rank() == 0) { std::vector<std::string> v; boost::mpi::gather<std::string>(world, "", v, 0); std::ostream_iterator<std::string> out{std::cout, "n"}; std::copy(v.begin(), v.end(), out); } else if (world.rank() == 1) { boost::mpi::gather(world, std::string{"Hello, world!"}, 0); } else if (world.rank() == 2) { boost::mpi::gather(world, std::string{"Hello, moon!"}, 0); } }
範例 47.9 在多個程序中呼叫函數 boost::mpi::gather()。函數是傳送還是接收取決於引數。
等級為 1 和 2 的程序使用 boost::mpi::gather() 傳送資料。它們將傳送的資料作為引數傳遞——字串“Hello, world!”和“你好,月亮!” – 以及資料應傳輸到的程序的級別。由於 boost::mpi::gather() 不是成員函數,因此還必須傳遞 communicator world。
等級為 0 的程序呼叫 boost::mpi::gather() 來接收資料。由於資料必須儲存在某個地方,因此傳遞了一個 std::vector<std::string> 型別的物件。請注意,您必須將此型別與 boost::mpi::gather() 一起使用。不支援其他容器或字串型別。
排名 0 的程序必須傳遞與排名 1 和 2 的程序相同的引數。這就是排名 0 的程序也傳遞 world、要傳送的字串和 0 到 boost::mpi::gather() 的原因。
如果您使用三個程序啟動範例 47.9,您好,世界!和你好,月亮!被顯示。如果仔細檢視輸出,您會注意到首先寫入了一個空行。第一行是等級為 0 的程序傳遞給 boost::mpi::gather() 的空字串。 v 中有三個字串,它們是從等級為 0、1 和 2 的程序接收的。向量中元素的索引對應於程序的等級。如果多次執行該範例,您將始終得到一個空字串作為向量中的第一個元素,“Hello, world!”作為第二個元素和“你好,月亮!”作為第三個。
請注意,您不得使用超過三個程序執行範例 47.9。例如,如果您使用 -n 4 啟動 mpiexec,則不會顯示任何資料。該程式將掛起,必須使用 CTRL+C 中止。
必須對所有程序執行集體操作。如果您的程式呼叫諸如 boost::mpi::gather() 之類的函數,您必須確保該函數在所有程序中都被呼叫。否則就違反了 MPI 標準。因為像 boost::mpi::gather() 這樣的函數必須被所有程序呼叫,所以每個程序的呼叫通常沒有不同,如範例 47.9 所示。將前面的範例與執行相同操作的範例 47.10 進行比較。
範例 47.10。使用 gather() 從所有程序收集資料
#include <boost/mpi.hpp> #include <boost/serialization/string.hpp> #include <vector> #include <string> #include <iterator> #include <algorithm> #include <iostream> int main(int argc, char *argv[]) { boost::mpi::environment env{argc, argv}; boost::mpi::communicator world; std::string s; if (world.rank() == 1) s = "Hello, world!"; else if (world.rank() == 2) s = "Hello, moon!"; std::vector<std::string> v; boost::mpi::gather(world, s, v, 0); std::ostream_iterator<std::string> out{std::cout, "n"}; std::copy(v.begin(), v.end(), out); }
您為所有流程中的集體操作呼叫函數。通常函數的定義方式很清楚必須執行哪個操作,即使所有程序都傳遞相同的引數。
範例 47.10 使用 boost::mpi::gather() 來收集資料。資料在其等級作為最後一個引數傳遞給 boost::mpi::gather() 的過程中收集。此程序收集它從所有程序接收的資料。儲存資料的向量僅供收集資料的程序使用。
boost::mpi::gather() 從所有程序收集資料。這包括收集資料的過程。在範例 47.10 中,這是等級為 0 的程序。該程序在 s 中向自身傳送一個空字串。空字串儲存在 v 中。正如您將在以下範例中看到的,集合操作始終包括所有程序。
您可以使用任意數量的程序執行範例 47.10,因為每個程序都會呼叫 boost::mpi::gather()。如果您使用三個程序執行該範例,結果將與前面的範例類似。
範例 47.11。在所有程序中使用 scatter() 分散資料
#include <boost/mpi.hpp> #include <boost/serialization/string.hpp> #include <vector> #include <string> #include <iostream> int main(int argc, char *argv[]) { boost::mpi::environment env{argc, argv}; boost::mpi::communicator world; std::vector<std::string> v{"Hello, world!", "Hello, moon!", "Hello, sun!"}; std::string s; boost::mpi::scatter(world, v, s, 0); std::cout << world.rank() << ": " << s << 'n'; }
範例 47.11 介紹了函數 boost::mpi::scatter()。它與 boost::mpi::gather() 相反。 boost::mpi::gather() 將來自多個程序的資料收集到一個程序中,而 boost::mpi::scatter() 將來自一個程序的資料分散到多個程序中。
範例 47.11 將來自排名為 0 的程序的 v 中的資料分散到所有程序,包括它自己。等級為 0 的程序接收到字串“Hello, world!”在 s 中,排名為 1 的程序收到“你好,月亮!”在 s 中,等級為 2 的程序收到“Hello, sun!”秒。
範例 47.12。使用 broadcast() 向所有程序傳送資料
#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; std::string s; if (world.rank() == 0) s = "Hello, world!"; boost::mpi::broadcast(world, s, 0); std::cout << s << 'n'; }
boost::mpi::broadcast() 將資料從一個程序傳送到所有程序。此函數與 boost::mpi::scatter() 之間的區別在於將相同的資料傳送到所有程序。在範例 47.12 中,所有程序都收到字串“Hello, world!”在 s 中寫下你好,世界!到標準輸出流。
範例 47.13。使用 reduce() 收集和分析資料
#include <boost/mpi.hpp> #include <boost/serialization/string.hpp> #include <string> #include <iostream> std::string min(const std::string &lhs, const std::string &rhs) { return lhs.size() < rhs.size() ? lhs : rhs; } int main(int argc, char *argv[]) { boost::mpi::environment env{argc, argv}; boost::mpi::communicator world; std::string s; if (world.rank() == 0) s = "Hello, world!"; else if (world.rank() == 1) s = "Hello, moon!"; else if (world.rank() == 2) s = "Hello, sun!"; std::string result; boost::mpi::reduce(world, s, result, min, 0); if (world.rank() == 0) std::cout << result << 'n'; }
boost::mpi::reduce() 從多個程序收集資料,如 boost::mpi::gather()。但是,資料不儲存在向量中。 boost::mpi::reduce() 需要一個函數或函數物件,它將用於分析資料。
如果您使用三個程序執行範例 47.13,則排名為 0 的程序會收到字串“Hello, sun!”結果。對 boost::mpi::reduce() 的呼叫收集並分析所有程序傳遞給它的字串。它們使用函數 min() 進行分析,該函數作為第四個引數傳遞給 boost::mpi::reduce()。 min() 比較兩個字串並返回較短的一個。
如果您使用三個以上的程序執行範例 47.13,則會顯示一個空字串,因為排名大於 2 的所有程序都會將一個空字串傳遞給 boost::mpi::reduce()。將顯示空字串,因為它比“Hello, sun!”短
範例 47.14。使用 all_reduce() 收集和分析資料
#include <boost/mpi.hpp> #include <boost/serialization/string.hpp> #include <string> #include <iostream> std::string min(const std::string &lhs, const std::string &rhs) { return lhs.size() < rhs.size() ? lhs : rhs; } int main(int argc, char *argv[]) { boost::mpi::environment env{argc, argv}; boost::mpi::communicator world; std::string s; if (world.rank() == 0) s = "Hello, world!"; else if (world.rank() == 1) s = "Hello, moon!"; else if (world.rank() == 2) s = "Hello, sun!"; std::string result; boost::mpi::all_reduce(world, s, result, min); std::cout << world.rank() << ": " << result << 'n'; }
範例 47.14 使用函數 boost::mpi::all_reduce(),它像 boost::mpi::reduce() 一樣收集和分析資料。這兩個函數之間的區別在於 boost::mpi::all_reduce() 將分析結果傳送到所有程序,而 boost::mpi::reduce() 使結果僅可用於排名作為傳遞的程序最後一個引數。因此,沒有排名傳遞給 boost::mpi::all_reduce()。如果您使用三個程序執行範例 47.14,每個程序都會寫入 Hello, sun!到標準輸出流。
到此這篇關於C++集體資料交換實現範例講解的文章就介紹到這了,更多相關C++集體資料交換內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45