多处理或多线程我的功能,怎么样?
multi-processing or multi-threading my function, how?
我对 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()
我需要运行 50,000 栋房屋的此功能,每栋房屋都有特定的雨水箱尺寸、屋顶面积和需水时间序列。我可以通过将函数放入循环中并遍历房屋来做到这一点。由于每个模拟都是完全独立的(它们只需要访问相同的输入雨阵列),我在想也许我可以在 python 中使用多线程或多处理来加速模拟。我了解了它们之间的区别,但无法弄清楚我应该使用哪一个。
我尝试了多重处理(水池和映射函数)来并行简化函数的版本,该函数只将雨水 numpy 数组作为输入(假设水箱大小和屋顶面积对于每个房屋和用水需求都是相同的)总是不变的。简化的原因是我无法理解如何引入多个参数。我有 20 个房子要模拟。循环方法明显快于多处理方法。我尝试了不同数量的池从 2 到20. 我尝试使用管理选项在进程之间共享降雨数据,但没有成功。我读了很多书,但它们非常先进且难以理解。希望能提供有关如何并行函数的提示或对类似的例子。
简短的回答是:
如果您的函数是 CPU-bound - 使用多处理,如果是 IO-bound - 使用多线程。
答案有点长:
Python有一个很棒的特性叫做GIL,这个锁提供了巨大的限制:一个文件在某一时刻只能由一个线程解释。所以如果你有很多计算,多线程看起来像是并行执行,但实际上在特定时刻只有一个线程处于活动状态。
因此多线程有利于IO绑定操作,例如数据下载,您可以将文件设置为在一个线程中下载并在不同的线程中执行其他操作,而不是等待下载完成。
所以,如果要进行并行计算,还是用multiprocessing比较好。 但是你不应该忘记每个进程都有自己的 RAM(在多线程中 RAM 是在线程之间共享的)。
UPD
有多种方法可以在进程之间共享内存,您可以在此处找到更多信息:https://docs.python.org/2/library/multiprocessing.html#exchanging-objects-between-processes。
我对 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()
我需要运行 50,000 栋房屋的此功能,每栋房屋都有特定的雨水箱尺寸、屋顶面积和需水时间序列。我可以通过将函数放入循环中并遍历房屋来做到这一点。由于每个模拟都是完全独立的(它们只需要访问相同的输入雨阵列),我在想也许我可以在 python 中使用多线程或多处理来加速模拟。我了解了它们之间的区别,但无法弄清楚我应该使用哪一个。
我尝试了多重处理(水池和映射函数)来并行简化函数的版本,该函数只将雨水 numpy 数组作为输入(假设水箱大小和屋顶面积对于每个房屋和用水需求都是相同的)总是不变的。简化的原因是我无法理解如何引入多个参数。我有 20 个房子要模拟。循环方法明显快于多处理方法。我尝试了不同数量的池从 2 到20. 我尝试使用管理选项在进程之间共享降雨数据,但没有成功。我读了很多书,但它们非常先进且难以理解。希望能提供有关如何并行函数的提示或对类似的例子。
简短的回答是:
如果您的函数是 CPU-bound - 使用多处理,如果是 IO-bound - 使用多线程。
答案有点长:
Python有一个很棒的特性叫做GIL,这个锁提供了巨大的限制:一个文件在某一时刻只能由一个线程解释。所以如果你有很多计算,多线程看起来像是并行执行,但实际上在特定时刻只有一个线程处于活动状态。
因此多线程有利于IO绑定操作,例如数据下载,您可以将文件设置为在一个线程中下载并在不同的线程中执行其他操作,而不是等待下载完成。
所以,如果要进行并行计算,还是用multiprocessing比较好。 但是你不应该忘记每个进程都有自己的 RAM(在多线程中 RAM 是在线程之间共享的)。
UPD
有多种方法可以在进程之间共享内存,您可以在此处找到更多信息:https://docs.python.org/2/library/multiprocessing.html#exchanging-objects-between-processes。