最近在忙,快一兩週沒更新了,今天簡單說下如何實現openfoam內的並行通訊
說到並行通訊倒不必恐慌,只是不同核之間資料傳遞,比如說咱們模擬開16個核,3號計算單元對4號計算單元說句」hello「,然後4號再回復」hi「,類似這樣
是不是很像不同的微訊號傳遞訊息,
其實咱們每個個體對於整個社會而言也是不同的核
假如現在我開個工廠,並行開16個核可以打比方作為我這個廠子有16個工人
咱這個廠子對於我們模擬工作者來說就是生產海量的資料
為了讓工廠的效率最高,兄弟們需要心往一處使,力往一處用
如何讓大家齊心合力,靠的是溝通
大家有沒有發現最近幾十年生活節奏越來越快了,這是因為我們的通訊成本越來越低了
因為有了資訊傳輸更及時有效,社會分工越來越細緻,整個社會的效率也越來越高
我們如果想把我們的模擬效率提上一個層次,必須要實現核與核之間的資訊傳輸,讓模擬分工更細緻,弟兄們齊心協力生產資料
我們首先想下用微信把訊息傳送出去需要幾步
1.登入微訊號 → 初始化
2.知道對方微訊號 → 程序ID
3.輸入文字 → 準備資料
4.點選傳送 → send
5.傳送成功(當然也有可能網不好或者被拉黑傳送失敗) → 狀態檢查
6.退出微信 → 結束程序
簡述一下,開啟冰箱,放進大象,關上冰箱,easy
openfoam內利用PstreamBuffers類封裝大象,openfoam對其解釋如下:
Description:
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Use UOPstream to stream data into buffers, call finishedSends() to
notify that data is in buffers and then use IUPstream to get data out
of received buffers. Works with both blocking and nonBlocking. Does
not make much sense with scheduled since there you would not need these
explicit buffers.
大概意思就是用於傳輸資訊流的中間載體,利用finishedSends()表示結束傳送
甚至在註釋下方寫明瞭如何使用
PstreamBuffers pBuffers(Pstream::commsTypes::nonBlocking);
for (label proci = 0; proci < Pstream::nProcs(); proci++)
{
if (proci != Pstream::myProcNo())
{
someObject vals;
UOPstream str(proci, pBuffers);
str << vals;
}
}
pBuffers.finishedSends(); // no-op for blocking
for (label proci = 0; proci < Pstream::nProcs(); proci++)
{
if (proci != Pstream::myProcNo())
{
UIPstream str(proci, pBuffers);
someObject vals(str);
}
}
大概解釋下這個程式的意思:
第一句是建立一個PstreamBuffers類,Pstream::commsTypes::nonBlocking意思是非阻塞通訊,Pstream::commsTypes列舉類內有三個列舉,
enum class commsTypes
{
blocking,
scheduled,
nonBlocking
};
分別對應的是阻塞通訊,計時通訊,非阻塞通訊,
接下來跑了一個迴圈,對除自己以外所有處理器進行了遍歷,將someObject vals輸送到快取中
pBuffers.finishedSends()說我這邊傳送完成
下面這個迴圈用UIPstream類進行接收
接下我們用openfoam實現
首先建立新案例
foamNewApp comm_parallel
隨便拷貝一個能並行的算例到資料夾中命名debug_case
接下來我們對幫助檔案中的範例程式進行照貓畫虎的改寫:
{
if (Pstream::parRun())
{
string s1 , s2;
int source = 0;//源頭處理器
int destination = 1;//目的地處理器
PstreamBuffers pBuffers(Pstream::commsTypes::nonBlocking);
if (Pstream::myProcNo() == source)
{
Pout << "這是處理器 No:" << Pstream::myProcNo() << endl;
string s1 = "安警官新年快樂!";
Pout << s1 << endl;
UOPstream send(destination , pBuffers);
send << s1;
Pout << "資訊已傳送!" << endl;
Pout << "==============================" << endl;
}
pBuffers.finishedSends();
PstreamBuffers pBuffers_1(Pstream::commsTypes::nonBlocking);
if (Pstream::myProcNo() == destination)
{
UIPstream recv(source , pBuffers);
recv >> s1;
if (s1 == "安警官新年快樂!")
{
Pout << "這是處理器 No:" << Pstream::myProcNo() << endl;
Pout << "收到資訊!" << endl;
s2 = "心明眼亮,平平安安";
}
UOPstream send(source , pBuffers_1);
send << s2;
Pout << "資訊已回覆!" << endl;
Pout << "==============================" << endl;
}
pBuffers_1.finishedSends();
if (Pstream::myProcNo() == source)
{
UIPstream recv(destination , pBuffers_1);
recv >> s2;
Pout << "這是處理器 No:" << Pstream::myProcNo() << endl;
Pout << s2 << endl;
}
}
}
以下是輸出結果:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Create time
[0] 這是處理器 No:0
[0] "安警官新年快樂!"
[0] 資訊已傳送!
[0] ==============================
[1] 這是處理器 No:1
[1] 收到資訊!
[1] 資訊已回覆!
[1] ==============================
[0] 這是處理器 No:0
[0] "心明眼亮,平平安安"
ExecutionTime = 0.08 s ClockTime = 0 s
End
Finalising parallel run
至此完成了openfoam體系內的處理器之間簡單的通訊
過幾天找時間再寫下如何像微信一樣群發資料,儘量用類別範本去寫,無論是檔案、語音或者是文字圖片,都可以在核與核之間溝通
確實科研之路踽踽獨行,無聊時讓處理器之間相互問候倒是成了一個小樂趣