我正在为我的研究创建一些小型生物信息学程序的 Rust 实现。我的主要考虑因素之一是性能,虽然我知道我可以使用 qsub 安排 Rust 程序在网格上运行——我可以访问的集群使用 Oracle 的 GridEngine——但我担心我没有打电话的事实MPI 直接会导致 Rust 程序出现性能问题。
在不使用 MPI 库的情况下调度程序会极大地影响性能吗?我应该在 Rust 中使用 MPI 库吗?如果是,是否有任何已知的 Rust 的 MPI 库?我已经找了一个,但我什么也没找到。
我正在为我的研究创建一些小型生物信息学程序的 Rust 实现。我的主要考虑因素之一是性能,虽然我知道我可以使用 qsub 安排 Rust 程序在网格上运行——我可以访问的集群使用 Oracle 的 GridEngine——但我担心我没有打电话的事实MPI 直接会导致 Rust 程序出现性能问题。
在不使用 MPI 库的情况下调度程序会极大地影响性能吗?我应该在 Rust 中使用 MPI 库吗?如果是,是否有任何已知的 Rust 的 MPI 库?我已经找了一个,但我什么也没找到。
我使用过几种超级计算工具(我是天体物理学家)并且经常面临同样的问题:我非常了解 C/C++,但更喜欢使用其他语言。
一般来说,除 MPI 之外的任何方法都可以,但考虑到此类超级计算机通常具有高度优化的 MPI 库,通常为集成在集群中的特定硬件量身定制。如果不使用 MPI,很难说 Rust 程序的性能会受到多大影响,但最安全的选择是继续使用集群上提供的 MPI 实现。
在像 MPI 库这样的 C 库周围使用 Rust 包装器并没有性能损失,因为瓶颈是在节点之间传输数据(例如通过 MPI_Send)所需的时间,而不是额外函数调用的可忽略成本。(此外,Rust 不是这种情况:没有额外的函数调用,如上所述。)
然而,尽管 Rust 提供了非常好的 FFI,但创建 MPI 绑定并不容易。问题在于 MPI 不是一个库,而是一个规范。流行的 MPI 库是 OpenMPI ( http://www.open-mpi.org ) 和 MPICH ( http://www.mpich.org )。它们中的每一个在实现标准的方式上都略有不同,它们通常使用 C 预处理器宏来覆盖这些差异。很少有 FFI 能够处理复杂的宏;我不知道 Rust 在这里得分如何。
例如,我在 Free Pascal 中实现了一个 MPI 程序,但我无法使用现有的 MPICH 绑定 ( http://wiki.lazarus.freepascal.org/MPICH ),因为我使用的集群提供了自己的 MPI由于上述原因,我更喜欢使用这个库。我无法重用 MPICH 绑定,因为他们认为像 MPI_BYTE 这样的常量是硬编码的整数常量。但在我的情况下,它们是指向似乎在调用 MPI_Init 时创建的不透明结构的指针。
Julia 与 MPI ( https://github.com/lcw/MPI.jl ) 的绑定通过在安装期间运行 C 和 Fortran 程序来解决此问题,这些程序会生成具有此类常量的正确值的 Julia 代码。参见例如https://github.com/lcw/MPI.jl/blob/master/deps/make_f_const.f
在我的情况下,我更喜欢实现一个中间件,即一个小型 C 库,它使用更“可预测”的接口包装 MPI 调用。(这或多或少也是 Python 和 Ocaml 绑定所做的,请参阅https://forge.ocamlcore.org/projects/ocamlmpi/和 http://mpi4py.scipy.org。)事情进展顺利,到目前为止我没有任何问题。
在不使用 MPI 库的情况下调度程序会极大地影响性能吗?
有很多方法可以进行并行计算。MPI 就是其中之一,正如对您问题的评论表明您可以通过一些体操从 Rust 调用 MPI。
但是还有其他方法,例如 PGAS 系列(Chapel、OpenSHMEM、Co-array Fortran),或者像 Charm++ 使用的替代消息传递。
MPI“简单地”提供了一个(非常有用、高度可移植、积极优化的)消息传递抽象,但只要您有某种方法来管理并行性,您就可以在集群上运行任何东西。