2014-02-27 100 views
1

以下是使用python进行多处理的示例程序。我发现每个进程的内存使用量比每个进程应该使用的内存高出2到3倍。如果我只用一个进程来计算,所用的内存就会多1.3倍,并且随着进程数量的增加而增加。Python多处理内存管理多维数组上的循环

例如,对于带有float64的1000 * 1000 * 1000的数组,它应该使用8Gb的内存,但我看到内存高达25Gb,并行运行8个处理器!但我读过多处理使用共享内存。所以我不确定内存在哪里泄漏。这里是代码:

#To use the code, please take care of your RAM. 
#If you have higher RAM, kindly try for the bigger arrays to see the difference clearly. 

from numpy import * 
import multiprocessing as mp 

a = arange(0, 2500, 5) 
b = arange(0, 2500, 5) 
c = arange(0, 2500, 5) 
a0 = 540. #random values 
b0 = 26. 
c0 = 826. 
def rand_function(a, b, c, a0, b0, c0): 
    Nloop = 100. 
    def loop(Nloop, out): 
     res_total = zeros((500, 500, 500), dtype = 'float') 
     n = 1 
     while n <= Nloop: 
      rad = sqrt((a-a0)**2 + (b-b0)**2 + (c-c0)**2) 
      res_total = res_total + rad 
      n +=1 
     out.put(res_total) 
    out = mp.Queue() 
    jobs = [] 
    Nprocs = mp.cpu_count() 
    print "No. of processors : ", Nprocs 
    for i in range(Nprocs): 
     p = mp.Process(target = loop, args=(Nloop/Nprocs, out)) 
     jobs.append(p) 
     p.start() 

    final_result = zeros((500,500,500), dtype = 'float') 

    for i in range(Nprocs): 
     final_result = final_result + out.get() 

    p.join() 
test = rand_function(a,b,c,a0, b0, c0) 

任何人都可以请告诉我哪里的内存泄漏?以及如何克服?非常感谢你提前。

+1

您认为这是“应该使用”多少?为什么? –

+0

例如,对于1000 * 1000 * 1000的数组,应该为float64使用(1000 * 1000 * 1000 * 8)/(1024 ** 3)Gb的内存。对?我也通过给出一个.nbytes来验证,你会知道使用的内存。 – geekygeek

+0

Just jound this:included into Python 3.4 [tracemalloc](http://docs.python.org/3.4/library/tracemalloc.html) – User

回答

2

使用存储器(的很多)有些东西:

  1. res_total
  2. res_total = res_total + rad右手侧创建临时数组,对于一个时刻,res_total同时存在。使用+=可以避免这种情况。
  3. out.put(res_total)泡菜阵列,使用大致相同的内存量。

这应该解释为什么内存使用可以远高于1。

+0

谢谢! 2.完成。但是3,有没有办法来克服'out.put(u_total)'酸洗? – geekygeek

+2

@geekygeek您可以尝试避免队列中的大数据和[在共享内存中使用numpy数组进行多处理](http://stackoverflow.com/q/7894791/222914)。 –

+0

谢谢!有没有一种方法可以避免使用零数组初始化'res_total'或'final_result'?因为这也有助于增加内存。 – geekygeek

1

在一个不相关的说明中,如果您想要做的是并行处理大量数组,最好使用multiprocessing.Pool,这样您就不必亲自处理循环的输出值。此外,您的代码不会将相同的任务分配给所有不同的工作进程,我不确定这是否是有意的。

import numpy as np 
import multiprocessing as mp 


def loop(arg): 
    max_n, a, b, c, a0, b0, c0 = arg 
    res_total = np.zeros(shape, dtype=np.float) 
    print 'starting' 
    for _ in range(max_n): 
     rad = np.sqrt((a - a0) ** 2 + (b - b0) ** 2 + (c - c0) ** 2) 
     res_total = res_total + rad 
    print 'done' 
    return res_total 


def rand_function(a, b, c, a0, b0, c0): 
    c_cpu = mp.cpu_count() 
    n_loop = 10 
    print "No. of processors : ", c_cpu 
    pool = mp.Pool(c_cpu) 
    out = pool.map(loop, [(n_loop/c_cpu, a, b, c, a0, b0, c0) 
          for _ in range(c_cpu)]) 

    print 'collating' 
    final_result = np.zeros(shape, dtype='float') 
    for i in out: 
     final_result += i 
    print final_result.shape 


shape = (50, 50, 50) 
rand_function(np.arange(0, 250, 5), np.arange(0, 250, 5), 
        np.arange(0, 250, 5), 540, 26, 826) 

在我的机器周围的内存技嘉每个工作进程的用户。您的原始代码每个工作人员使用1.4GB左右(然后增长到2GB)。我怀疑这与输出队列被修改有关,这会触发操作系统的写时复制(尽管我不确定)。

+0

我看到multiprocessing.Pool使用比multiprocessing.Process更多的内存。对于较小的阵列,您看不到太多差异。如果我使用'multiprocessing.Pool'运行上述解决方案,就像您为500 * 500 * 500的数组所提供的那样,我会看到内存达到18Gb。而'multiprocessing.Process'则达到12Gb,这仍然很高。 – geekygeek