为什么调用scipy.ndimage.center_of_mass后内存使用率很高?

tkclm6bt  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(96)

我使用scipy.ndimage模块来获取关于3D数组中标记对象的信息。我正在尝试减少这个进程使用的内存,因为它是一个瓶颈,限制了我们可以在计算服务器上运行的并行进程的数量。我注意到,在调用center_of_mass函数之后,内存使用量急剧增加,并且与函数返回的数据大小不匹配。我这样调用函数:

ndimage.center_of_mass(values, labels, range(1,np.max(labels)+1))

valueslabels的形状是(20, 2048, 2048)。在调用center_of_mass之前,我使用资源模块打印出内存使用情况:

print(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss)

然后调用center_of_mass后再次打印。之前,它报告了6504168,之后它给出了11255620,因此内存使用量增加了近5 GB。但是从center_of_mass返回的形状是(24187884, 3),它应该只需要大约580 MB的内存(通过检查ndarray上的nbytes来确认)。我还用top监视进程,进程继续使用更多的内存,所以这不仅仅是函数调用期间内存使用的临时高峰。
是什么导致了内存使用量的如此巨大的跳跃?有什么办法可以减少吗?

sgtfey8w

sgtfey8w1#

虽然很容易估计numpy数组(本质上是nbytes,或8*num_elements)的内存使用,但元组列表的内存使用需要更多的工作。
让我们测试一个10元组的随机浮点数列表。

In [136]: import sys    
In [137]: alist = [tuple(np.random.rand(3)) for _ in range(10)]

列表本身- 10个指针加上一些开销:

In [138]: sys.getsizeof(alist)
Out[138]: 184

所有10个元组的大小:

In [139]: sum([sys.getsizeof(a) for a in alist])
Out[139]: 640

和其中一个元组中的浮点数:

In [140]: sum([sys.getsizeof(i) for i in alist[0]])
Out[140]: 96

所以总共是:

In [141]: 184+640+10*96
Out[141]: 1784

将其与等效数组(10,3)的nbytes进行比较:

In [142]: np.array(alist).nbytes
Out[142]: 240       # 10*3*8

所以元组列表占用的内存是数组的7.4倍。
现在缩放到你的(n,3)数组:

In [143]: 24187884 * 1784/10
Out[143]: 4315118505.6    
In [144]: _/1e9
Out[144]: 4.3151185056

In [145]: 11255620-6504168
Out[145]: 4751452

这就是你的5G
比我希望的要好:)
center_maas函数的源代码,可以在文档中找到,结尾是:

return [tuple(v) for v in numpy.array(results).T]

相关问题