我正在Linux上开发一个c ++代码,它可能耗尽内存,进入交换并显着减速,有时会崩溃。我想通过允许用户指定进程可以用尽的总系统内存比例的限制来防止这种情况发生。如果程序应该超过这个限制,那么代码可以输出一些中间结果,并且干净地终止。
我可以通过从/ proc / self / stat读取驻留集大小来确定正在使用多少内存。然后,我可以在所有并行进程中对此进行总结,以便为程序提供总内存使用量。
可通过调用sysconf(_SC_PHYS_PAGES)获得可用的总系统内存(参见How to get available memory C++/g++?)。但是,如果我在并行集群上运行,那么这个数字可能只会给我当前集群节点的总内存。例如,我可能在4个集群节点上运行48个进程(每个节点有12个核心)。
所以,我真正的问题是如何找出运行给定进程的处理器?然后,我可以总结在同一个集群节点上运行的进程使用的内存,并将其与该节点上的可用内存进行比较,如果该程序在运行该程序的任何节点上超过指定的百分比,则终止该程序。我会为此使用sched_getcpu(),但遗憾的是我正在使用glibc 2.5版本的系统进行编译和运行,而sched_getcpu()仅在glibc 2.6中引入。此外,由于集群在旧的Linux OS(版本2.6.18)上使用,我也不能使用syscall()来调用getcpu()!有没有其他方法可以获得处理器号或处理器的任何类型的标识符,以便我可以分别在每个处理器上使用的内存总和?
或者有更好的方法来解决问题吗?我愿意接受建议。
答案 0 :(得分:0)
运行良好的集群会将您的工作置于某种形式的资源限制之下(RLIMIT_AS或cgroups)。您只需致电setrlimit(RLIMIT_AS,...)
即可自行完成此操作。我认为你担心sysconf会使事情过于复杂,因为在共享集群上,你没有理由认为你的代码应该使用甚至固定的物理内存大小。相反,你应该选择一个合理的内存要求(如果你的集群还没有提供一个 - 大多数调度程序都能很好地进行内存调度。)即使你坚持自己做,自动调整大小,你也不需要知道正在使用哪些核心:只需确定您的进程在节点上的副本数量,并进行适当划分。 (当然,您需要确定每个进程正在运行的节点(主机)。)
值得指出的是内核RLIMIT_AS,而不是RLIMIT_RSS。当你达到这个限制时,新的分配将失败。
最后,我质疑一个使用无界内存的程序的设计。你确定没有更好的算法吗?如果在计算中投入大量时间后,用户会发现你的程序非常恼火,它会决定尝试分配更多,然后失败。有时人们在错误地认为分配尽可能多的内存会给他们更好的IO缓冲(这是天真的页面缓存等)时会问这类问题。