gpt4 book ai didi

linux - MPI_SEND 占用很大一部分虚拟内存

转载 作者:IT王子 更新时间:2023-10-29 00:24:09 26 4
gpt4 key购买 nike

在大量内核上调试我的程序时,我遇到了非常奇怪的虚拟内存不足错误。我的调查导致代码和平,主人向每个奴隶发送小消息。然后我写了一个小程序,其中 1 个主机使用 MPI_SEND 发送 10 个整数,所有从机使用 MPI_RECV 接收它。比较MPI_SEND前后的/proc/self/status文件,内存大小的差异是巨大的!最有趣的事情(它使我的程序崩溃)是此内存不会在 MPI_Send 之后释放,并且仍然占用大量空间。

有什么想法吗?

 System memory usage before MPI_Send, rank: 0
Name: test_send_size
State: R (running)
Pid: 7825
Groups: 2840
VmPeak: 251400 kB
VmSize: 186628 kB
VmLck: 72 kB
VmHWM: 4068 kB
VmRSS: 4068 kB
VmData: 71076 kB
VmStk: 92 kB
VmExe: 604 kB
VmLib: 6588 kB
VmPTE: 148 kB
VmSwap: 0 kB
Threads: 3

System memory usage after MPI_Send, rank 0
Name: test_send_size
State: R (running)
Pid: 7825
Groups: 2840
VmPeak: 456880 kB
VmSize: 456872 kB
VmLck: 257884 kB
VmHWM: 274612 kB
VmRSS: 274612 kB
VmData: 341320 kB
VmStk: 92 kB
VmExe: 604 kB
VmLib: 6588 kB
VmPTE: 676 kB
VmSwap: 0 kB
Threads: 3

最佳答案

这是几乎所有在 InfiniBand 上运行的 MPI 实现的预期行为。 IB RDMA 机制要求数据缓冲区应该被注册,即它们首先被锁定在物理内存中的一个固定位置,然后驱动程序告诉 InfiniBand HCA 如何将虚拟地址映射到物理内存。注册供 IB HCA 使用的内存非常复杂,因此过程非常缓慢,这就是为什么大多数 MPI 实现从不注销曾经注册过的内存,希望相同的内存稍后用作源或数据目标。如果注册的内存是堆内存,它永远不会返回给操作系统,这就是为什么您的数据段的大小只会增加。

尽可能重复使用发送和接收缓冲区。请记住,通过 InfiniBand 进行的通信会产生高内存开销。大多数人并没有真正考虑过这一点,而且通常没有很好的文档记录,但是 InfiniBand 使用了许多特殊的数据结构(队列),这些数据结构分配在进程的内存中,并且这些队列随着进程的数量而显着增长。在某些完全连接的情况下,队列内存量可能非常大,以至于实际上没有内存留给应用程序。

有一些参数可以控制英特尔 MPI 使用的 IB 队列。在您的案例中,最重要的是 I_MPI_DAPL_BUFFER_NUM,它控制预分配和预注册内存的数量。它的默认值为 16,因此您可能希望减小它。但是请注意可能的性能影响。您还可以通过将 I_MPI_DAPL_BUFFER_ENLARGEMENT 设置为 1 来尝试使用动态预分配缓冲区大小。启用此选项后,英特尔 MPI 将首先注册小缓冲区,然后在需要时增加它们。另请注意,IMPI 延迟打开连接,这就是为什么您仅在调用 MPI_Send 后才会看到已用内存大幅增加的原因。

如果不使用 DAPL 传输,例如改用 ofa 传输,您无能为力。您可以通过将 I_MPI_OFA_USE_XRC 设置为 1 来启用 XRC 队列。这应该以某种方式减少使用的内存。如果您的程序的通信图未完全连接(完全连接的程序是一个完全连接的程序,其中每个等级与所有其他等级对话)。

关于linux - MPI_SEND 占用很大一部分虚拟内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13088772/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com