0

我正在 Linux 上开发一个 c++ 代码,它可能会耗尽内存、进入交换状态并显着减慢,有时甚至会崩溃。我想通过允许用户指定进程可以用完的总系统内存的比例限制来防止这种情况发生。如果程序超过这个限制,那么代码可以输出一些中间结果,并干净地终止。

我可以通过从 /proc/self/stat 读取驻留集大小来确定正在使用多少内存。然后我可以在所有并行进程中总结这一点,从而为我提供程序的总内存使用量。

可用的总系统内存可以通过调用 sysconf(_SC_PHYS_PAGES) 获得(请参阅如何获得可用内存 C++/g++?)。但是,如果我在并行集群上运行,那么大概这个数字只会给我当前集群节点的总内存。例如,我可能在 4 个集群节点(每个节点有 12 个核心)上运行 48 个进程。

所以,我真正的问题是如何找出给定进程在哪个处理器上运行?然后,我可以总结在同一集群节点上运行的进程使用的内存,并将其与该节点上的可用内存进行比较,如果这超过程序运行的任何节点上的指定百分比,则终止程序。我会为此使用 sched_getcpu(),但不幸的是,我正在使用 glibc 2.5 版的系统上编译和运行,而 sched_getcpu() 仅在 glibc 2.6 中引入。此外,由于集群在旧的 linux 操作系统(版本 2.6.18)上使用,我也不能使用 syscall() 来调用 getcpu() !有没有其他方法可以获取处理器编号或处理器的任何类型的标识符,以便我可以分别汇总每个处理器使用的内存?

或者有没有更好的方法来解决这个问题?我愿意接受建议。

4

1 回答 1

0

一个运行良好的集群会将您的作业置于某种形式的资源限制(RLIMIT_AS 或 cgroups)之下。您可以自己调用setrlimit(RLIMIT_AS,...). 我认为您担心 sysconf 会使事情变得过于复杂,因为在共享集群上,没有理由认为您的代码甚至应该使用物理内存大小的固定部分。相反,您应该选择一个合理的内存要求(如果您的集群还没有提供一个 - 大多数调度程序都可以很好地进行内存调度。)即使您坚持自己做,自动调整大小,您也不需要知道正在使用哪些核心:只需弄清楚节点上有多少个进程副本,然后适当划分即可。(当然,您需要弄清楚每个进程在哪个节点(主机)上运行。)

值得指出的是内核是 RLIMIT_AS,而不是 RLIMIT_RSS。当你达到这个限制时,新的分配将会失败。

最后,我质疑使用无限内存的程序的设计。你确定没有更好的算法吗?如果在计算上投入大量时间后,用户会发现您的程序使用起来非常烦人,它决定尝试分配更多,然后失败。有时人们会在错误地认为分配尽可能多的内存会给他们更好的 IO 缓冲(这是天真的 wrt 页面缓存等)时提出这类问题。

于 2013-07-14T23:40:35.900 回答