使用 MPI/OpenMP 的具有派生数据类型(嵌套类对象)容器的 C++ 程序
Posted
技术标签:
【中文标题】使用 MPI/OpenMP 的具有派生数据类型(嵌套类对象)容器的 C++ 程序【英文标题】:C++ program with derived data type (nested class object) container using MPI/OpenMP 【发布时间】:2018-04-03 23:25:40 【问题描述】:我用 C++11 开发了一个程序,我想加快性能。
我会用一个简单的例子来展示程序的结构(不完整)。
//main.cpp
#include "a.h"
int main()
std::vector<a> a_container;
for (auto i=0; i< 10K; i++)
a a_obj;
a_container.push_back(a_obj);
for(time = 1; time< long_time; time++)
//i used openmp here already
for (auto i=0; i< 10K; i++)
a_container[i].dosomething();
for (auto i=0; i< 10K; i++)
a_container[i].update();
return 1;
//a.cpp
//a.h
#include "b.h"
class a
int d;
b b_obj;
int dosomething();
//b.cpp
//b.h
class b
int c;
double d;
int dosomething();
所以为了加快程序,我想同时使用 MPI 和 OpenMP,主要用于循环(可能高达 100 万~10 亿个实例)。
类对象 a 和 b 都包含复杂的成员变量(标准和其他容器等)和函数。
通过使用 OpenMP,我可以利用一个具有所有内核/线程的 HPC 节点。但是如果我想使用 MPI,我需要将所有实例分发到许多节点。
我还没有找到一个好的解决方案,我现在最接近的是; http://mpi-forum.org/docs/mpi-2.2/mpi22-report/node83.htm#Node83 和https://blogs.cisco.com/performance/how-to-send-cxx-stl-objects-in-mpi 请提供一些建议。谢谢。
【问题讨论】:
【参考方案1】:通过 MPI 发送不可复制的对象与通过任何其他字节传输发送它们相同:您必须进行序列化。如果有帮助,您可以使用stringstream
在任一端保存缓冲区。
但是,您很可能根本不应该这样做。 创建您的对象所需的数据(例如、循环边界和初始值)可能比用于持续计算的形式更小更简单。改为发送它,您可以并行创建复杂的对象并减少通信。 (如果参数是静态已知的,则无需发送任何内容:每个进程都可以开始处理已知的初始化。)
【讨论】:
感谢您的想法。根据您的第二个选项,我现在有了一个通用的解决方案。为了利用多个节点,我可以使用 MPI 在节点之间进行通信。因为大多数成员变量都可以在本地读取或计算,所以我只需要传递某种索引来控制节点和对象实例。有了这个,我需要一个并行输入/输出 (PIO) 方案来允许所有节点都可以读取和写入数据。困难的部分是所有实例都会在时间步内与其他实例进行通信,因此通信是不可避免的,但可以是简单的结构(字符串流等)。以上是关于使用 MPI/OpenMP 的具有派生数据类型(嵌套类对象)容器的 C++ 程序的主要内容,如果未能解决你的问题,请参考以下文章
确保混合 MPI / OpenMP 在不同的内核上运行每个 OpenMP 线程