openfoam并行通信探索(一)

发布时间 2023-03-22 19:15:23作者: TJUHE

前言

最近在忙,快一两周没更新了,今天简单说下如何实现openfoam内的并行通信


为什么要并行通信

说到并行通信倒不必恐慌,只是不同核之间数据传递,比如说咱们仿真开16个核,3号计算单元对4号计算单元说句”hello“,然后4号再回复”hi“,类似这样

是不是很像不同的微信号传递消息,
其实咱们每个个体对于整个社会而言也是不同的核

假如现在我开个工厂,并行开16个核可以打比方作为我这个厂子有16个工人
咱这个厂子对于我们仿真工作者来说就是生产海量的数据
为了让工厂的效率最高,兄弟们需要心往一处使,力往一处用

如何让大家齐心合力,靠的是沟通
大家有没有发现最近几十年生活节奏越来越快了,这是因为我们的通信成本越来越低了
因为有了信息传输更及时有效,社会分工越来越细致,整个社会的效率也越来越高

我们如果想把我们的仿真效率提上一个层次,必须要实现核与核之间的信息传输,让仿真分工更细致,弟兄们齐心协力生产数据


并行通信在openfoam中的实现

我们首先想下用微信把消息发送出去需要几步
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体系内的处理器之间简单的通信


结语

确实科研之路踽踽独行,无聊时让处理器之间相互问候倒是成了一个小乐趣


一起探索openfoam也是相当有趣的一件事,非常欢迎私信讨论
指正的价值要比打赏更重要,下面是个人联系方式,希望能结交到志同道合的朋友
image