1

我对python很陌生。我需要使用下面的函数来模拟雨水罐一个简单的水平衡:多处理或多线程我的功能如何?

def rain_tank_model(rain, water_demand,roof_area, tank_size, household_name): 

    # rain and water_demand time series are numpy arrays with over than 8 million recordings. 
    # each houshold has installed a rain tank with a specific size 

    v = [] # water volume in tanks 
    spill = [] # amount of water spills from rain tank 
    unmet_demand = [] # amount of unmet water demand 
    volume = 0.0 # stored volume at the start of the simulation 
    for i in range(len(rain)): 
     volume += rain[i] * roof_area - water_demand[i] 
     if volume < 0. : #volume cannot be negative 
      unmet_demand.append(volume * -1) 
      volume = 0 
      v.append(volume) 
      spill.append(0.) 
     if volume > tank_size: #water should spill from the tank 
      spill.append(volume - tank_size) 
      volume = tank_size 
      v.append(volume) 
      unmet_demand.append(0.) 
     else: 
      spill.append(0.) 
      v.append(volume) 
      unmet_demand.append(0.) 

    file = open(str(household_name)+".txt", 'w') 
    for i in range(len(v)): 
     line =str(v[i])+"\t"+str(spill[i])+"\t"+str(unmet_demand[i])+"\n" 
     file.write(line) 
    file.close() 

我需要50000个房子在运行该函数都有一个特定的雨槽尺寸,屋顶面积和水需求的时间序列。我可以通过将函数放入循环并遍历房屋来实现此目的。由于每个模拟是完全独立的(他们只需要访问相同的输入雨阵),我想也许我可以在python中使用多线程或多处理来加速模拟。我读了他们之间的差异,但不知道我应该使用哪一个。

我尝试了多处理(水池和地图功能)来并行简化版本的功能,只需要雨量为numpy的数组作为输入(假设水箱尺寸和屋顶面积对于每个房屋和水需求是相同的总是不变的,简化的原因是我不明白如何引入多个参数,我有20个房子可以模拟,循环方法比多处理方法快得多,我尝试了从2到20个不同数量的池。我尝试使用管理选项来共享流程之间的雨量数据,但没有成功。我读了很多,但它们非常先进,难以理解。请多多关注如何平行化函数或任何类似的参考例子

回答

0

简短的回答是:

如果你的函数是CPU绑定的 - 使用多处理,如果IO绑定 - 使用多线程。

的时间长一点的回答:

Python有所谓GIL一个很大的特点,这把锁提供了巨大的限制:一个文件可以由一个线程的一个时刻来解释。所以如果你有很多的计算,多线程将看起来像并行执行,但事实上,在特定时刻只有一个线程处于活动状态。

因此,多线程适合IO绑定操作,例如数据下载,您可以将文件设置为在一个线程中下载并执行其他操作,而不是等待下载完成。

所以,如果你想执行并行计算,最好使用多处理。 但是你不应该忘记每个进程都有它自己的RAM(在多线程RAM之间共享线程)。

UPD

有办法有进程间共享内存,你可以在这里找到更多的信息:https://docs.python.org/2/library/multiprocessing.html#exchanging-objects-between-processes

+0

有没有简单的方法可以判断哪一个是我的功能? –

+0

正如我可以看到你不执行任何IO操作,如文件下载/上传/等。所以我会去多处理。 – vovaminiof

+0

我现在明白你的解释。根据您提供的较长答案,每个进程都有自己的RAM。这是否意味着每个进程都会创建自己的输入数据副本?如果是,是否有共享输入数据(如全局参数)? –