如何使用MPI发送和接收二叉树?

时间:2019-06-19 08:27:57

标签: c mpi

我想使用某些功能将一个二进制树从一个内核发送到另一个内核 像MPI_Send()。还是有任何快速算法可以实现此功能?

我使用的数据结构是

typedef struct BiNode{
    struct BiNode *lchi,*rchi;
    struct BiNode *parent;
    char *name;
}BiNode;

此二叉树有2000多片叶子。

2 个答案:

答案 0 :(得分:2)

详细了解serialization。在当前的机器和网络上,一棵2000节点的树是一小部分数据。如果平均名称长度是十几个字节,则需要传输几十个千字节(今天已经不算什么了)。典型的数据中心网络带宽为100 MB /秒,inter-process communication(例如在同一处理器的内核之间使用某些pipe(7)unix(7) sockets)通常至少快十倍。另请参见http://norvig.com/21-days.html

  

还是有任何快速算法可以实现此功能?

您可能需要进行depth-first遍历(可能没有更快的速度了。)

您可能会考虑以某种文本格式(或某种text-based protocol)来编写树,例如(使用JSON(或XML或YAML或S-expressions)(某些自定义变体)。然后利用现有的JSON库,例如Jansson。它们能够在动态分配的字符串缓冲区中对数据(以JSON格式)进行编码和解码。

如果性能至关重要,请考虑使用某种二进制格式,例如XDRASN-1。或者使用现有的压缩库(也许是zlib)来压缩JSON(或其他文本)编码。

我的猜测是,在您的情况下,这样做是不值得的(使用JSON更容易编写代码,并且开发时间具有一定的成本和价值)。您的瓶颈可能是网络本身,而不是任何软件层。但是您需要进行基准测试。

答案 1 :(得分:0)

MPI具有称为数据类型的功能。完整的解释可能需要很长的时间,但您可能希望查看其中的结构(尽管您可能可以根据向量的布局来摆脱向量)。

但是,您可能不能仅仅使用MPI数据类型,因为您将只传输一堆指针,这对另一端的进程毫无意义。取而代之的是,您必须确定实际需要发送的部分并以一种有意义的方式对其进行序列化。

所以我想您有几个选择。

  1. 更改树在内存中的布局方式,使之成为连续内存的数组,您上面具有的所有指针都将成为数组中的索引。

    • 这在您的应用程序上下文中可能实际上没有任何意义,但是它使“树”非常易于传输。此时,您可以只发送一个大字节数组,也可以构造MPI数据类型来描述该数组中的每个单元格,并发送2000个字节数组。
  2. 根据源数据(无论是文件还是其他内容)在另一个进程上重新创建树。

    • 这可能不是您要找的答案,并且如果您是从应用程序中间的任何非平凡数据中生成此数据的,也无济于事。
  3. 使用POSIX共享内存。

    • 由于您在问题的描述中说“核心”,因此我假设您要在同一台物理计算机上的OS进程之间传输数据。在这种情况下,您可以使用共享内存,而根本不需要进行消息传递。只需打开一个共享内存区域,并与另一个进程连接,然后“欺骗”另一端的所有数据即可。只要您共享这些指针指向的所有内存,我就可以了。