服务器上做并行计算,内存足够,但内存不足报错

本人在一个40核的服务器(win系统)上运行Julia程序。服务器的内存40G,还有近30G的虚拟内存分页。

当我运行下面代码后

R=rand{Float64}(10_000_000,50)
G=zeros(ComplexF64,(10_000_000,50))
H=zeros(ComplexF64,(10_000_000,50))

系统可以正常运行后续的代码(后边的代码做串行计算)。这三个矩阵占的内存总大小为:$10^7\times 50 \times(8+16+16)=20$G,程序能运行符合预期。

此后,当我运行代码

using Distributed, SharedArrays
addprocs()

Julia程序IDE-jupyterlab-要么崩溃,要么程序一直不响应(CPU几乎没占用,内存没改变)。重启后先运行上面代码,addprocs()能正常运行,给出40个worker可用的结果,此时系统的内存和没开启julia时几乎一样(29%)。然后,当我运行定义一开始的这三个矩阵的代码,系统则报内存溢出错误。后续尝试中发现:只定义第一个矩阵,Julia还可以做一些计算。但再定义剩下的任一个矩阵,则报错。

因为我接触Julia的时间还非常短,网上也没找到类似的问题,所以搞了几天到现在不知道该怎么解决。

请问,为什么会这样?该怎么避免,让后续程序能跑起来?

你这里描述的太模糊了

你前面说的能正常计算,有监控计算过程中内存占用的峰值么?addprocs()之后,有使用到并行计算相关的东西么?我看你用了SharedArrays,中间可能的情况太多了。

建议你可以逐步增加worker数量试试

谢谢您的建议!

同样的并行代码,更大一点的矩阵,我在Mac Pro(8核,32G内存)上跑,完全没问题。

SharedArray是用来定义另外一个固定大小的矩阵,预先分配了大小,它占内存大小不到1G(800M左右)。并行计算就是为了计算子循环中这个矩阵里的所有元素,节省时间。后边会涉及到一些“小”矩阵的乘法,以及加法。因为矩阵运算本身是多线程的,所以并没有对其进行并行编程。

整个程序作串行计算的时候,用掉服务器总内存77%左右。因为计算量很大,全部串行计算的话,预估要24天才能完成。

理想情况下,在mac pro上要跑3天左右。如果服务器40核能跑起来的话,可能会快一些。因为要跑很多组情况,对计算时间就很在意了。

减少worker数肯定是一个出路。

另外,矩阵大小都改成(10_000_000,10),编写的程序也可以正常运行。大小改成(10_000_000,20)后,这三个矩阵的引入就和开上40个worker成了你死我亡的状态。这个现象很难理解,我在猜:会不会是每个worker要均匀地分配总内存了?但我没找到相关的材料说明。

这个靠猜没法判断的…

从你的描述来看,多半是因为你这几个矩阵相关的计算里,有部分数据需要分发到每个进程里,导致各个进程都单独进行了拷贝,你可以从这个角度都分析分析你的代码

谢谢您的关注和回复!

我现在碰到的问题是在开始并行计算之前,Julia就出问题了,后边的并行计算还没开展。就是两种情况:1.预分配了三个大矩阵的内存,开启distributed和sharedarrys的包(成功),然后开40个进程(失败),结果是Julia程序不响应;2.先开40个进程(成功),然后在worker1中定义三个大矩阵(未使用@everywhere,按理其它worker不可见),程序报内存溢出错误,失败。

因为还没给worker1外的进程分配任何东西,所以我觉得费解。

40个核分布在两块区域,每个区域20个。只要运行的进程数超过20个,程序就会出现各种报错,报一些未知函数等。在20个进程以下(含)时都能正常运行。具体原因是什么不清楚,大致只能说两块区域之间存在某些未知问题。

会不会是内存碎片问题?如果可以的话,考虑重启一下服务器看看。我在几年前用 tensorflow 时也出现过类似问题:明明有很多空闲内存,但报内存不够的错误,最后通过重启解决了这个问题。

谢谢!

期间服务器让我跑崩溃过几次,是跑MMA跑的,有重启过。您倒是提醒到我,服务器的硬盘坏道应该不少,老家伙了。